mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-10-12 15:35:15 +00:00
Merge branch 'release/4.6.7'
This commit is contained in:
@@ -5,6 +5,7 @@ APP_KEY=SomeRandomStringOf32CharsExactly
|
||||
APP_LOG=daily
|
||||
APP_LOG_LEVEL=warning
|
||||
APP_URL=http://localhost
|
||||
TRUSTED_PROXIES=
|
||||
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=127.0.0.1
|
||||
@@ -42,7 +43,7 @@ CACHE_PREFIX=firefly
|
||||
|
||||
EXCHANGE_RATE_SERVICE=fixerio
|
||||
|
||||
GOOGLE_MAPS_API_KEY=
|
||||
MAPBOX_API_KEY=
|
||||
ANALYTICS_ID=
|
||||
SITE_OWNER=mail@example.com
|
||||
USE_ENCRYPTION=true
|
||||
|
@@ -19,10 +19,10 @@ install:
|
||||
- mkdir -p build/logs
|
||||
|
||||
script:
|
||||
- phpunit -c phpunit.xml
|
||||
- phpunit -c phpunit.coverage.xml
|
||||
|
||||
#after_success:
|
||||
# - travis_retry php vendor/bin/coveralls -x storage/build/clover.xml
|
||||
after_success:
|
||||
- travis_retry php vendor/bin/coveralls -x storage/build/clover-all.xml
|
||||
|
||||
# safelist
|
||||
branches:
|
||||
|
34
CHANGELOG.md
34
CHANGELOG.md
@@ -2,7 +2,27 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
This project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
## [4.6.6] - 2015-05-25
|
||||
## [4.6.7] - 2017-10-09
|
||||
### Added
|
||||
- #872, reported @gavu
|
||||
|
||||
### Fixed
|
||||
- #878, fixed by @Findus23
|
||||
- #881, reported by @nicoschreiner
|
||||
- #884, by @gavu
|
||||
- #840, reported by @MacPaille
|
||||
- #882, reported by @nicoschreiner
|
||||
- #891, #892, reported by @nicoschreiner
|
||||
- #891, reported by @gavu
|
||||
- #827, fixed by @pkoziol
|
||||
- #903, fixed by @hduijn
|
||||
- #904, reported by @gavu
|
||||
- #910, reported by @gavu
|
||||
- #911, reported by @gavu
|
||||
- #915, reported by @TomWis97
|
||||
- #917, reported by @Wr0ngName
|
||||
|
||||
## [4.6.6] - 2017-09-30
|
||||
### Added
|
||||
- #826, reported by @pkoziol.
|
||||
- #855, by @ms32035
|
||||
@@ -369,7 +389,7 @@ An intermediate release because something in the Twig and Twigbridge libraries i
|
||||
### Security
|
||||
- #519, thanks to [xpfgsyb](https://github.com/xpfgsyb)
|
||||
|
||||
## [4.3.0] - 2015-12-26
|
||||
## [4.3.0] - 2016-12-26
|
||||
### Added
|
||||
- New method of keeping track of available budget, see issue #489
|
||||
- Support for Spanish
|
||||
@@ -562,7 +582,7 @@ An intermediate release because something in the Twig and Twigbridge libraries i
|
||||
- #336
|
||||
- #338 found by [roberthorlings](https://github.com/roberthorlings)
|
||||
|
||||
## [4.0.0] - 2015-09-26
|
||||
## [4.0.0] - 2016-09-26
|
||||
### Added
|
||||
- Upgraded to Laravel 5.3, most other libraries upgraded as well.
|
||||
- Added GBP as currency, thanks to [Mortalife](https://github.com/Mortalife)
|
||||
@@ -577,7 +597,7 @@ An intermediate release because something in the Twig and Twigbridge libraries i
|
||||
- Various bugs, thanks to [fuf](https://github.com/fuf), [sandermulders](https://github.com/sandermulders) and [vissert](https://github.com/vissert)
|
||||
- Various queries optimized for MySQL 5.7
|
||||
|
||||
## [3.10.4] - 2015-09-14
|
||||
## [3.10.4] - 2016-09-14
|
||||
### Fixed
|
||||
- Migration fix by [sandermulders](https://github.com/sandermulders)
|
||||
- Tricky import bug fix thanks to [vissert](https://github.com/vissert)
|
||||
@@ -641,7 +661,7 @@ An intermediate release because something in the Twig and Twigbridge libraries i
|
||||
- Fixed various bugs in the piggy banks pages.
|
||||
- Fixed a bug in the `firefly:verify` routine
|
||||
|
||||
## [3.10] - 2015-05-25
|
||||
## [3.10] - 2016-08-12
|
||||
### Added
|
||||
- New charts in year report
|
||||
- Can add / remove money from piggy bank on mobile device.
|
||||
@@ -668,11 +688,11 @@ An intermediate release because something in the Twig and Twigbridge libraries i
|
||||
- Bulk update problems, #280, thanks [stickgrinder](https://github.com/stickgrinder)
|
||||
- Fixed various problems with amount reporting of split transactions.
|
||||
|
||||
## [3.9.1]
|
||||
## [3.9.1] - 2016-06-06
|
||||
### Fixed
|
||||
- Fixed a bug where removing money from a piggy bank would not work. See issue #265 and #269
|
||||
|
||||
## [3.9.0]
|
||||
## [3.9.0] - 2016-05-22
|
||||
### Added
|
||||
- [zjean](https://github.com/zjean) has added code that allows you to force "https://"-URL's.
|
||||
- [tonicospinelli](https://github.com/tonicospinelli) has added Portuguese (Brazil) translations.
|
||||
|
@@ -47,6 +47,9 @@ COPY . $FIREFLY_PATH
|
||||
RUN chown -R www-data:www-data /var/www && chmod -R 775 $FIREFLY_PATH/storage
|
||||
|
||||
RUN composer install --prefer-dist --no-dev --no-scripts
|
||||
RUN composer dump-autoload
|
||||
RUN php artisan firefly:instructions install
|
||||
RUN php artisan optimize
|
||||
|
||||
EXPOSE 80
|
||||
|
||||
|
@@ -43,7 +43,8 @@ class CreateImport extends Command
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'firefly:create-import
|
||||
protected $signature
|
||||
= 'firefly:create-import
|
||||
{file : The file to import.}
|
||||
{configuration : The configuration file to use for the import/}
|
||||
{--type=csv : The file type of the import.}
|
||||
|
@@ -20,9 +20,11 @@ use FireflyIII\Models\AccountMeta;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\BudgetLimit;
|
||||
use FireflyIII\Models\LimitRepetition;
|
||||
use FireflyIII\Models\Note;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Models\TransactionJournalMeta;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||
use Illuminate\Console\Command;
|
||||
@@ -76,6 +78,8 @@ class UpgradeDatabase extends Command
|
||||
$this->line('Updating currency information..');
|
||||
$this->updateTransferCurrencies();
|
||||
$this->updateOtherCurrencies();
|
||||
$this->line('Done updating currency information..');
|
||||
$this->migrateNotes();
|
||||
$this->info('Firefly III database is up to date.');
|
||||
|
||||
return;
|
||||
@@ -281,6 +285,29 @@ class UpgradeDatabase extends Command
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Move all the journal_meta notes to their note object counter parts.
|
||||
*/
|
||||
private function migrateNotes(): void
|
||||
{
|
||||
$set = TransactionJournalMeta::whereName('notes')->get();
|
||||
/** @var TransactionJournalMeta $meta */
|
||||
foreach ($set as $meta) {
|
||||
$journal = $meta->transactionJournal;
|
||||
$note = $journal->notes()->first();
|
||||
if (is_null($note)) {
|
||||
$note = new Note;
|
||||
$note->noteable()->associate($journal);
|
||||
}
|
||||
|
||||
$note->text = $meta->data;
|
||||
$note->save();
|
||||
Log::debug(sprintf('Migrated meta note #%d to Note #%d', $meta->id, $note->id));
|
||||
$meta->delete();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method makes sure that the transaction journal uses the currency given in the transaction.
|
||||
|
@@ -27,6 +27,7 @@ trait VerifiesAccessToken
|
||||
{
|
||||
/**
|
||||
* Abstract method to make sure trait knows about method "option".
|
||||
*
|
||||
* @param null $key
|
||||
*
|
||||
* @return mixed
|
||||
|
@@ -47,6 +47,7 @@ class Kernel extends ConsoleKernel
|
||||
* Define the application's command schedule.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Schedule $schedule
|
||||
*
|
||||
* @return void
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*/
|
||||
|
@@ -14,7 +14,6 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Export\Entry;
|
||||
|
||||
use FireflyIII\Models\Transaction;
|
||||
use Steam;
|
||||
|
||||
/**
|
||||
* To extend the exported object, in case of new features in Firefly III for example,
|
||||
|
@@ -49,6 +49,7 @@ class AdminEventHandler
|
||||
Session::flash('error', 'Possible email error: ' . $e->getMessage());
|
||||
}
|
||||
Log::debug('If no error above this line, message was sent.');
|
||||
|
||||
// @codeCoverageIgnoreEnd
|
||||
return true;
|
||||
}
|
||||
|
@@ -314,6 +314,7 @@ class JournalCollector implements JournalCollectorInterface
|
||||
return $this;
|
||||
}
|
||||
$this->joinBudgetTables();
|
||||
Log::debug('Journal collector will filter for budgets', $budgetIds);
|
||||
|
||||
$this->query->where(
|
||||
function (EloquentBuilder $q) use ($budgetIds) {
|
||||
@@ -433,8 +434,11 @@ class JournalCollector implements JournalCollectorInterface
|
||||
public function setRange(Carbon $start, Carbon $end): JournalCollectorInterface
|
||||
{
|
||||
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'));
|
||||
$startStr = $start->format('Y-m-d');
|
||||
$endStr = $end->format('Y-m-d');
|
||||
$this->query->where('transaction_journals.date', '>=', $startStr);
|
||||
$this->query->where('transaction_journals.date', '<=', $endStr);
|
||||
Log::debug(sprintf('JournalCollector range is now %s - %s (inclusive)', $startStr, $endStr));
|
||||
}
|
||||
|
||||
return $this;
|
||||
|
@@ -13,7 +13,6 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use Amount;
|
||||
use Carbon\Carbon;
|
||||
use ExpandedForm;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
@@ -73,7 +72,7 @@ class AccountController extends Controller
|
||||
$repository = app(CurrencyRepositoryInterface::class);
|
||||
$allCurrencies = $repository->get();
|
||||
$currencySelectList = ExpandedForm::makeSelectList($allCurrencies);
|
||||
$defaultCurrency = Amount::getDefaultCurrency();
|
||||
$defaultCurrency = app('amount')->getDefaultCurrency();
|
||||
$subTitleIcon = config('firefly.subIconsByIdentifier.' . $what);
|
||||
$subTitle = trans('firefly.make_new_' . $what . '_account');
|
||||
$roles = [];
|
||||
@@ -244,6 +243,7 @@ class AccountController extends Controller
|
||||
|
||||
/**
|
||||
* Show an account.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param JournalRepositoryInterface $repository
|
||||
* @param Account $account
|
||||
@@ -332,7 +332,7 @@ class AccountController extends Controller
|
||||
|
||||
// update preferences if necessary:
|
||||
$frontPage = Preferences::get('frontPageAccounts', [])->data;
|
||||
if (count($frontPage) > 0) {
|
||||
if (count($frontPage) > 0 && $account->accountType->type === AccountType::ASSET) {
|
||||
$frontPage[] = $account->id;
|
||||
Preferences::set('frontPageAccounts', $frontPage);
|
||||
}
|
||||
|
@@ -17,8 +17,8 @@ namespace FireflyIII\Http\Controllers\Admin;
|
||||
use FireflyIII\Events\AdminRequestedTestMessage;
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Session;
|
||||
use Log;
|
||||
use Session;
|
||||
|
||||
/**
|
||||
* Class HomeController
|
||||
@@ -49,6 +49,7 @@ class HomeController extends Controller
|
||||
Log::debug(sprintf('Now in testMessage() controller. IP is %s', $ipAddress));
|
||||
event(new AdminRequestedTestMessage(auth()->user(), $ipAddress));
|
||||
Session::flash('info', strval(trans('firefly.send_test_triggered')));
|
||||
|
||||
return redirect(route('admin.index'));
|
||||
}
|
||||
|
||||
|
@@ -14,7 +14,6 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Http\Controllers\Auth;
|
||||
|
||||
use FireflyConfig;
|
||||
use FireflyIII\Events\UserChangedEmail;
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Cookie\CookieJar;
|
||||
|
@@ -13,7 +13,6 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use Amount;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Helpers\Collector\JournalCollectorInterface;
|
||||
use FireflyIII\Http\Requests\BillFormRequest;
|
||||
@@ -131,7 +130,7 @@ class BillController extends Controller
|
||||
$this->rememberPreviousUri('bills.edit.uri');
|
||||
}
|
||||
|
||||
$currency = Amount::getDefaultCurrency();
|
||||
$currency = app('amount')->getDefaultCurrency();
|
||||
$bill->amount_min = round($bill->amount_min, $currency->decimal_places);
|
||||
$bill->amount_max = round($bill->amount_max, $currency->decimal_places);
|
||||
|
||||
|
@@ -13,7 +13,6 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use Amount;
|
||||
use Carbon\Carbon;
|
||||
use Exception;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
@@ -199,7 +198,7 @@ class BudgetController extends Controller
|
||||
$periodStart = $start->formatLocalized($this->monthAndDayFormat);
|
||||
$periodEnd = $end->formatLocalized($this->monthAndDayFormat);
|
||||
$budgetInformation = $this->repository->collectBudgetInformation($budgets, $start, $end);
|
||||
$defaultCurrency = Amount::getDefaultCurrency();
|
||||
$defaultCurrency = app('amount')->getDefaultCurrency();
|
||||
$available = $this->repository->getAvailableBudget($defaultCurrency, $start, $end);
|
||||
$spent = array_sum(array_column($budgetInformation, 'spent'));
|
||||
$budgeted = array_sum(array_column($budgetInformation, 'budgeted'));
|
||||
@@ -268,7 +267,7 @@ class BudgetController extends Controller
|
||||
'earned' => '0',
|
||||
'suggested' => '0',
|
||||
];
|
||||
$currency = Amount::getDefaultCurrency();
|
||||
$currency = app('amount')->getDefaultCurrency();
|
||||
$range = Preferences::get('viewRange', '1M')->data;
|
||||
$begin = Navigation::subtractPeriod($start, $range, 3);
|
||||
|
||||
@@ -380,7 +379,7 @@ class BudgetController extends Controller
|
||||
{
|
||||
$start = Carbon::createFromFormat('Y-m-d', $request->string('start'));
|
||||
$end = Carbon::createFromFormat('Y-m-d', $request->string('end'));
|
||||
$defaultCurrency = Amount::getDefaultCurrency();
|
||||
$defaultCurrency = app('amount')->getDefaultCurrency();
|
||||
$amount = $request->get('amount');
|
||||
|
||||
$this->repository->setAvailableBudget($defaultCurrency, $start, $end, $amount);
|
||||
@@ -515,7 +514,7 @@ class BudgetController extends Controller
|
||||
*/
|
||||
public function updateIncome(Carbon $start, Carbon $end)
|
||||
{
|
||||
$defaultCurrency = Amount::getDefaultCurrency();
|
||||
$defaultCurrency = app('amount')->getDefaultCurrency();
|
||||
$available = $this->repository->getAvailableBudget($defaultCurrency, $start, $end);
|
||||
$available = round($available, $defaultCurrency->decimal_places);
|
||||
|
||||
|
@@ -153,7 +153,15 @@ class HomeController extends Controller
|
||||
public function routes()
|
||||
{
|
||||
$set = RouteFacade::getRoutes();
|
||||
$ignore = ['chart.', 'javascript.', 'json.', 'report-data.', 'popup.', 'debugbar.'];
|
||||
$ignore = ['chart.', 'javascript.', 'json.', 'report-data.', 'popup.', 'debugbar.', 'attachments.download', 'attachments.preview',
|
||||
'bills.rescan', 'budgets.income', 'currencies.def', 'error', 'flush', 'help.show', 'import.file',
|
||||
'login', 'logout', 'password.reset', 'profile.confirm-email-change', 'profile.undo-email-change',
|
||||
'register', 'report.options', 'routes', 'rule-groups.down', 'rule-groups.up', 'rules.up', 'rules.down',
|
||||
'rules.select', 'search.search', 'test-flash', 'transactions.link.delete', 'transactions.link.switch',
|
||||
'two-factor.lost', 'report.options',
|
||||
|
||||
];
|
||||
|
||||
/** @var Route $route */
|
||||
foreach ($set as $route) {
|
||||
$name = $route->getName();
|
||||
|
@@ -11,7 +11,6 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use Amount;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Account;
|
||||
@@ -90,17 +89,17 @@ class JavascriptController extends Controller
|
||||
public function variables(Request $request)
|
||||
{
|
||||
$localeconv = localeconv();
|
||||
$accounting = Amount::getJsConfig($localeconv);
|
||||
$accounting = app('amount')->getJsConfig($localeconv);
|
||||
$localeconv = localeconv();
|
||||
$defaultCurrency = Amount::getDefaultCurrency();
|
||||
$defaultCurrency = app('amount')->getDefaultCurrency();
|
||||
$localeconv['frac_digits'] = $defaultCurrency->decimal_places;
|
||||
$pref = Preferences::get('language', config('firefly.default_language', 'en_US'));
|
||||
$lang = $pref->data;
|
||||
$dateRange = $this->getDateRangeConfig();
|
||||
|
||||
$data = [
|
||||
'currencyCode' => Amount::getCurrencyCode(),
|
||||
'currencySymbol' => Amount::getCurrencySymbol(),
|
||||
'currencyCode' => app('amount')->getCurrencyCode(),
|
||||
'currencySymbol' => app('amount')->getCurrencySymbol(),
|
||||
'accounting' => $accounting,
|
||||
'localeconv' => $localeconv,
|
||||
'language' => $lang,
|
||||
|
@@ -13,16 +13,10 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use Amount;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Helpers\Collector\JournalCollectorInterface;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
||||
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
|
||||
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
|
||||
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
|
||||
use FireflyIII\Support\CacheProperties;
|
||||
use Illuminate\Http\Request;
|
||||
use Response;
|
||||
|
||||
|
@@ -13,7 +13,6 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use Amount;
|
||||
use Carbon\Carbon;
|
||||
use ExpandedForm;
|
||||
use FireflyIII\Http\Requests\PiggyBankFormRequest;
|
||||
@@ -277,14 +276,14 @@ class PiggyBankController extends Controller
|
||||
public function postAdd(Request $request, PiggyBankRepositoryInterface $repository, PiggyBank $piggyBank)
|
||||
{
|
||||
$amount = $request->get('amount');
|
||||
$currency = Amount::getDefaultCurrency();
|
||||
$currency = app('amount')->getDefaultCurrency();
|
||||
if ($repository->canAddAmount($piggyBank, $amount)) {
|
||||
$repository->addAmount($piggyBank, $amount);
|
||||
Session::flash(
|
||||
'success', strval(
|
||||
trans(
|
||||
'firefly.added_amount_to_piggy',
|
||||
['amount' => Amount::formatAnything($currency, $amount, false), 'name' => $piggyBank->name]
|
||||
['amount' => app('amount')->formatAnything($currency, $amount, false), 'name' => $piggyBank->name]
|
||||
)
|
||||
)
|
||||
);
|
||||
@@ -296,7 +295,10 @@ class PiggyBankController extends Controller
|
||||
Log::error('Cannot add ' . $amount . ' because canAddAmount returned false.');
|
||||
Session::flash(
|
||||
'error', strval(
|
||||
trans('firefly.cannot_add_amount_piggy', ['amount' => Amount::formatAnything($currency, $amount, false), 'name' => e($piggyBank->name)])
|
||||
trans(
|
||||
'firefly.cannot_add_amount_piggy',
|
||||
['amount' => app('amount')->formatAnything($currency, $amount, false), 'name' => e($piggyBank->name)]
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
@@ -313,12 +315,16 @@ class PiggyBankController extends Controller
|
||||
public function postRemove(Request $request, PiggyBankRepositoryInterface $repository, PiggyBank $piggyBank)
|
||||
{
|
||||
$amount = $request->get('amount');
|
||||
$currency = Amount::getDefaultCurrency();
|
||||
$currency = app('amount')->getDefaultCurrency();
|
||||
if ($repository->canRemoveAmount($piggyBank, $amount)) {
|
||||
$repository->removeAmount($piggyBank, $amount);
|
||||
Session::flash(
|
||||
'success',
|
||||
strval(trans('firefly.removed_amount_from_piggy', ['amount' => Amount::formatAnything($currency, $amount, false), 'name' => $piggyBank->name]))
|
||||
strval(
|
||||
trans(
|
||||
'firefly.removed_amount_from_piggy', ['amount' => app('amount')->formatAnything($currency, $amount, false), 'name' => $piggyBank->name]
|
||||
)
|
||||
)
|
||||
);
|
||||
Preferences::mark();
|
||||
|
||||
@@ -329,7 +335,10 @@ class PiggyBankController extends Controller
|
||||
|
||||
Session::flash(
|
||||
'error', strval(
|
||||
trans('firefly.cannot_remove_from_piggy', ['amount' => Amount::formatAnything($currency, $amount, false), 'name' => e($piggyBank->name)])
|
||||
trans(
|
||||
'firefly.cannot_remove_from_piggy',
|
||||
['amount' => app('amount')->formatAnything($currency, $amount, false), 'name' => e($piggyBank->name)]
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
|
@@ -63,7 +63,7 @@ class SearchController extends Controller
|
||||
|
||||
public function search(Request $request, SearchInterface $searcher)
|
||||
{
|
||||
$fullQuery = $request->get('query');
|
||||
$fullQuery = strval($request->get('query'));
|
||||
|
||||
// parse search terms:
|
||||
$searcher->parseQuery($fullQuery);
|
||||
|
@@ -97,7 +97,7 @@ class TagController extends Controller
|
||||
*/
|
||||
public function delete(Tag $tag)
|
||||
{
|
||||
$subTitle = trans('breadcrumbs.delete_tag', ['tag' => e($tag->tag)]);
|
||||
$subTitle = trans('breadcrumbs.delete_tag', ['tag' => $tag->tag]);
|
||||
|
||||
// put previous url in session
|
||||
$this->rememberPreviousUri('tags.delete.uri');
|
||||
@@ -157,10 +157,19 @@ class TagController extends Controller
|
||||
*/
|
||||
public function index(TagRepositoryInterface $repository)
|
||||
{
|
||||
|
||||
// collect tags by year:
|
||||
// start with oldest tag
|
||||
$oldestTag = $repository->oldestTag();
|
||||
/** @var Carbon $start */
|
||||
$start = new Carbon;
|
||||
if (!is_null($oldestTag)) {
|
||||
/** @var Carbon $start */
|
||||
$start = $oldestTag->date;
|
||||
}
|
||||
if (is_null($oldestTag)) {
|
||||
/** @var Carbon $start */
|
||||
$start = clone(session('first'));
|
||||
}
|
||||
|
||||
$now = new Carbon;
|
||||
$clouds = [];
|
||||
$clouds['no-date'] = $repository->tagCloud(null);
|
||||
|
@@ -23,6 +23,7 @@ use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Http\Requests\JournalFormRequest;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\Note;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
@@ -128,8 +129,15 @@ class SingleController extends Controller
|
||||
'payment_date' => $journal->getMeta('payment_date'),
|
||||
'invoice_date' => $journal->getMeta('invoice_date'),
|
||||
'internal_reference' => $journal->getMeta('internal_reference'),
|
||||
'notes' => $journal->getMeta('notes'),
|
||||
'notes' => '',
|
||||
];
|
||||
|
||||
/** @var Note $note */
|
||||
$note = $journal->notes()->first();
|
||||
if (!is_null($note)) {
|
||||
$preFilled['notes'] = $note->text;
|
||||
}
|
||||
|
||||
Session::flash('preFilled', $preFilled);
|
||||
|
||||
return redirect(route('transactions.create', [strtolower($journal->transactionType->type)]));
|
||||
@@ -270,7 +278,7 @@ class SingleController extends Controller
|
||||
'payment_date' => $journal->dateAsString('payment_date'),
|
||||
'invoice_date' => $journal->dateAsString('invoice_date'),
|
||||
'interal_reference' => $journal->getMeta('internal_reference'),
|
||||
'notes' => $journal->getMeta('notes'),
|
||||
'notes' => '',
|
||||
|
||||
// amount fields
|
||||
'amount' => $pTransaction->amount,
|
||||
@@ -283,6 +291,11 @@ class SingleController extends Controller
|
||||
'foreign_currency' => $foreignCurrency,
|
||||
'destination_currency' => $foreignCurrency,
|
||||
];
|
||||
/** @var Note $note */
|
||||
$note = $journal->notes()->first();
|
||||
if (!is_null($note)) {
|
||||
$preFilled['notes'] = $note->text;
|
||||
}
|
||||
|
||||
// amounts for withdrawals and deposits:
|
||||
// amount, native_amount, source_amount, destination_amount
|
||||
|
@@ -13,7 +13,6 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Http\Middleware;
|
||||
|
||||
use Amount;
|
||||
use App;
|
||||
use Carbon\Carbon;
|
||||
use Closure;
|
||||
@@ -109,7 +108,7 @@ class Range
|
||||
// save some formats:
|
||||
$monthAndDayFormat = (string)trans('config.month_and_day');
|
||||
$dateTimeFormat = (string)trans('config.date_time');
|
||||
$defaultCurrency = Amount::getDefaultCurrency();
|
||||
$defaultCurrency = app('amount')->getDefaultCurrency();
|
||||
|
||||
View::share('monthAndDayFormat', $monthAndDayFormat);
|
||||
View::share('dateTimeFormat', $dateTimeFormat);
|
||||
|
@@ -14,6 +14,7 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Http\Middleware;
|
||||
|
||||
use Fideloper\Proxy\TrustProxies as Middleware;
|
||||
use Illuminate\Contracts\Config\Repository;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class TrustProxies extends Middleware
|
||||
@@ -37,4 +38,19 @@ class TrustProxies extends Middleware
|
||||
* @var array
|
||||
*/
|
||||
protected $proxies;
|
||||
|
||||
/**
|
||||
* TrustProxies constructor.
|
||||
*
|
||||
* @param Repository $config
|
||||
*/
|
||||
public function __construct(Repository $config)
|
||||
{
|
||||
$trustedProxies = env('TRUSTED_PROXIES', null);
|
||||
if (!is_null($trustedProxies) && strlen($trustedProxies) > 0) {
|
||||
$this->proxies = $trustedProxies;
|
||||
}
|
||||
|
||||
parent::__construct($config);
|
||||
}
|
||||
}
|
||||
|
@@ -40,10 +40,11 @@ class TagFormRequest extends Request
|
||||
$latitude = null;
|
||||
$longitude = null;
|
||||
$zoomLevel = null;
|
||||
if ($this->get('setTag') === 'true') {
|
||||
$latitude = $this->string('latitude');
|
||||
$longitude = $this->string('longitude');
|
||||
$zoomLevel = $this->integer('zoomLevel');
|
||||
|
||||
if ($this->get('tag_position_has_tag') === 'true') {
|
||||
$latitude = $this->string('tag_position_latitude');
|
||||
$longitude = $this->string('tag_position_longitude');
|
||||
$zoomLevel = $this->integer('tag_position_zoomlevel');
|
||||
}
|
||||
|
||||
$data = [
|
||||
|
@@ -43,6 +43,7 @@ class Amount implements ConverterInterface
|
||||
Log::debug(sprintf('Start with amount "%s"', $value));
|
||||
$len = strlen($value);
|
||||
$decimalPosition = $len - 3;
|
||||
$altPosition = $len - 2;
|
||||
$decimal = null;
|
||||
|
||||
if (($len > 2 && $value{$decimalPosition} === '.') || ($len > 2 && strpos($value, '.') > $decimalPosition)) {
|
||||
@@ -53,6 +54,11 @@ class Amount implements ConverterInterface
|
||||
$decimal = ',';
|
||||
Log::debug(sprintf('Decimal character in "%s" seems to be a comma.', $value));
|
||||
}
|
||||
// decimal character is null? find out if "0.1" or ".1" or "0,1" or ",1"
|
||||
if ($len > 1 && ($value{$altPosition} === '.' || $value{$altPosition} === ',')) {
|
||||
$decimal = $value{$altPosition};
|
||||
Log::debug(sprintf('Alternate search resulted in "%s" for decimal sign.', $decimal));
|
||||
}
|
||||
|
||||
// if decimal is dot, replace all comma's and spaces with nothing. then parse as float (round to 4 pos)
|
||||
if ($decimal === '.') {
|
||||
|
52
app/Import/Specifics/SnsDescription.php
Normal file
52
app/Import/Specifics/SnsDescription.php
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
/**
|
||||
* snsDescription.php
|
||||
* Author 2017 hugovanduijn@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\Import\Specifics;
|
||||
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class SnsDescription
|
||||
*
|
||||
* @package FireflyIII\Import\Specifics
|
||||
*/
|
||||
class SnsDescription implements SpecificInterface
|
||||
{
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public static function getDescription(): string
|
||||
{
|
||||
return 'Trim quotes from SNS descriptions.';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public static function getName(): string
|
||||
{
|
||||
return 'SNS description';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $row
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function run(array $row): array
|
||||
{
|
||||
$row[17] = ltrim($row[17],"'");
|
||||
$row[17] = rtrim($row[17],"'");
|
||||
return $row;
|
||||
}
|
||||
}
|
@@ -16,6 +16,7 @@ use Exception;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Import\Object\ImportJournal;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Models\Note;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use Illuminate\Support\Collection;
|
||||
use Log;
|
||||
@@ -35,16 +36,15 @@ class ImportStorage
|
||||
/** @var Collection */
|
||||
public $journals;
|
||||
/** @var int */
|
||||
protected $defaultCurrencyId = 1;
|
||||
/** @var string */
|
||||
private $dateFormat = 'Ymd'; // yes, hard coded
|
||||
protected $defaultCurrencyId = 1; // yes, hard coded
|
||||
/** @var ImportJob */
|
||||
protected $job;
|
||||
/** @var Collection */
|
||||
private $objects;
|
||||
/** @var Collection */
|
||||
protected $rules;
|
||||
|
||||
/** @var string */
|
||||
private $dateFormat = 'Ymd';
|
||||
/** @var Collection */
|
||||
private $objects;
|
||||
/** @var array */
|
||||
private $transfers = [];
|
||||
|
||||
@@ -179,9 +179,14 @@ class ImportStorage
|
||||
|
||||
$this->storeBill($journal, $importJournal->bill->getBill());
|
||||
$this->storeMeta($journal, $importJournal->metaDates);
|
||||
$journal->setMeta('notes', $importJournal->notes);
|
||||
$this->storeTags($importJournal->tags, $journal);
|
||||
|
||||
// set notes for journal:
|
||||
$dbNote = new Note();
|
||||
$dbNote->noteable()->associate($journal);
|
||||
$dbNote->text = trim($importJournal->notes);
|
||||
$dbNote->save();
|
||||
|
||||
// set journal completed:
|
||||
$journal->completed = true;
|
||||
$journal->save();
|
||||
@@ -207,36 +212,48 @@ class ImportStorage
|
||||
*/
|
||||
private function isDoubleTransfer(array $parameters): bool
|
||||
{
|
||||
Log::debug('Check if is a double transfer.');
|
||||
if ($parameters['type'] !== TransactionType::TRANSFER) {
|
||||
Log::debug(sprintf('Is a %s, not a transfer so no.', $parameters['type']));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$amount = app('steam')->positive($parameters['amount']);
|
||||
$names = [$parameters['asset'], $parameters['opposing']];
|
||||
$transfer = [];
|
||||
$hit = false;
|
||||
|
||||
sort($names);
|
||||
|
||||
foreach ($this->transfers as $transfer) {
|
||||
$hits = 0;
|
||||
if ($parameters['description'] === $transfer['description']) {
|
||||
$hit = true;
|
||||
$hits++;
|
||||
Log::debug(sprintf('Description "%s" equals "%s", hits = %d', $parameters['description'], $transfer['description'], $hits));
|
||||
}
|
||||
if ($names === $transfer['names']) {
|
||||
$hit = true;
|
||||
$hits++;
|
||||
Log::debug(sprintf('Involved accounts, "%s" equals "%s", hits = %d', join(',', $names), join(',', $transfer['names']), $hits));
|
||||
}
|
||||
if (bccomp($amount, $transfer['amount']) === 0) {
|
||||
$hit = true;
|
||||
$hits++;
|
||||
Log::debug(sprintf('Amount %s equals %s, hits = %d', $amount, $transfer['amount'], $hits));
|
||||
}
|
||||
if ($parameters['date'] === $transfer['date']) {
|
||||
$hit = true;
|
||||
$hits++;
|
||||
Log::debug(sprintf('Date %s equals %s, hits = %d', $parameters['date'], $transfer['date'], $hits));
|
||||
}
|
||||
}
|
||||
if ($hit === true) {
|
||||
// number of hits is 4? Then it's a match
|
||||
if ($hits === 4) {
|
||||
Log::error(
|
||||
'There already is a transfer imported with these properties. Compare existing with new. ', ['existing' => $transfer, 'new' => $parameters]
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return $hit;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@@ -44,12 +44,10 @@ trait ImportSupport
|
||||
{
|
||||
/** @var int */
|
||||
protected $defaultCurrencyId = 1;
|
||||
|
||||
/** @var Collection */
|
||||
protected $rules;
|
||||
|
||||
/** @var ImportJob */
|
||||
protected $job;
|
||||
/** @var Collection */
|
||||
protected $rules;
|
||||
|
||||
/**
|
||||
* @param TransactionJournal $journal
|
||||
|
@@ -5,7 +5,6 @@ namespace FireflyIII\Mail;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Mail\Mailable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
|
||||
class UndoEmailChangeMail extends Mailable
|
||||
{
|
||||
|
@@ -48,7 +48,8 @@ class Note extends Model
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all of the owning noteable models. Currently only piggy bank
|
||||
* Get all of the owning noteable models. Currently piggy bank and
|
||||
* transaction journal
|
||||
*/
|
||||
public function noteable()
|
||||
{
|
||||
|
@@ -32,13 +32,13 @@ use Watson\Validating\ValidatingTrait;
|
||||
* @property int $foreign_currency_dp
|
||||
*
|
||||
* @property int $account_id
|
||||
* @property-read string $account_name
|
||||
* @property string $account_name
|
||||
* @property string $account_iban
|
||||
* @property string $account_number
|
||||
* @property string $account_bic
|
||||
* @property string $account_currency_code
|
||||
*
|
||||
* @property-read int $opposing_account_id
|
||||
* @property int $opposing_account_id
|
||||
* @property string $opposing_account_name
|
||||
* @property string $opposing_account_iban
|
||||
* @property string $opposing_account_number
|
||||
@@ -46,10 +46,10 @@ use Watson\Validating\ValidatingTrait;
|
||||
* @property string $opposing_currency_code
|
||||
*
|
||||
*
|
||||
* @property-read int $transaction_budget_id
|
||||
* @property-read string $transaction_budget_name
|
||||
* @property-read int $transaction_journal_budget_id
|
||||
* @property-read string $transaction_journal_budget_name
|
||||
* @property int $transaction_budget_id
|
||||
* @property string $transaction_budget_name
|
||||
* @property int $transaction_journal_budget_id
|
||||
* @property string $transaction_journal_budget_name
|
||||
*
|
||||
* @property-read int $transaction_category_id
|
||||
* @property-read string $transaction_category_name
|
||||
|
@@ -25,7 +25,7 @@ use Watson\Validating\ValidatingTrait;
|
||||
*/
|
||||
class TransactionCurrency extends Model
|
||||
{
|
||||
use SoftDeletes, ValidatingTrait;
|
||||
use SoftDeletes;
|
||||
|
||||
/**
|
||||
* The attributes that should be casted to native types.
|
||||
@@ -41,13 +41,6 @@ class TransactionCurrency extends Model
|
||||
];
|
||||
protected $dates = ['created_at', 'updated_at', 'deleted_at', 'date'];
|
||||
protected $fillable = ['name', 'code', 'symbol', 'decimal_places'];
|
||||
protected $rules
|
||||
= [
|
||||
'name' => 'required|between:1,48',
|
||||
'code' => 'required|between:3,3',
|
||||
'symbol' => 'required|between:1,8',
|
||||
'decimal_places' => 'required|min:0|max:12|numeric',
|
||||
];
|
||||
|
||||
/**
|
||||
* @param TransactionCurrency $currency
|
||||
|
@@ -260,6 +260,14 @@ class TransactionJournal extends Model
|
||||
return $this->transactionType->isWithdrawal();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all of the notes.
|
||||
*/
|
||||
public function notes()
|
||||
{
|
||||
return $this->morphMany('FireflyIII\Models\Note', 'noteable');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
|
@@ -52,6 +52,52 @@ class BudgetRepository implements BudgetRepositoryInterface
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This method collects various info on budgets, used on the budget page and on the index.
|
||||
*
|
||||
* @param Collection $budgets
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
public function collectBudgetInformation(Collection $budgets, Carbon $start, Carbon $end): array
|
||||
{
|
||||
// get account information
|
||||
/** @var AccountRepositoryInterface $accountRepository */
|
||||
$accountRepository = app(AccountRepositoryInterface::class);
|
||||
$accounts = $accountRepository->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET, AccountType::CASH]);
|
||||
$return = [];
|
||||
/** @var Budget $budget */
|
||||
foreach ($budgets as $budget) {
|
||||
$budgetId = $budget->id;
|
||||
$return[$budgetId] = [
|
||||
'spent' => $this->spentInPeriod(new Collection([$budget]), $accounts, $start, $end),
|
||||
'budgeted' => '0',
|
||||
'currentRep' => false,
|
||||
];
|
||||
$budgetLimits = $this->getBudgetLimits($budget, $start, $end);
|
||||
$otherLimits = new Collection;
|
||||
|
||||
// get all the budget limits relevant between start and end and examine them:
|
||||
/** @var BudgetLimit $limit */
|
||||
foreach ($budgetLimits as $limit) {
|
||||
if ($limit->start_date->isSameDay($start) && $limit->end_date->isSameDay($end)
|
||||
) {
|
||||
$return[$budgetId]['currentLimit'] = $limit;
|
||||
$return[$budgetId]['budgeted'] = $limit->amount;
|
||||
continue;
|
||||
}
|
||||
// otherwise it's just one of the many relevant repetitions:
|
||||
$otherLimits->push($limit);
|
||||
}
|
||||
$return[$budgetId]['otherLimits'] = $otherLimits;
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Budget $budget
|
||||
*
|
||||
@@ -222,53 +268,6 @@ class BudgetRepository implements BudgetRepositoryInterface
|
||||
return $set;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method collects various info on budgets, used on the budget page and on the index.
|
||||
*
|
||||
* @param Collection $budgets
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
public function collectBudgetInformation(Collection $budgets, Carbon $start, Carbon $end): array
|
||||
{
|
||||
// get account information
|
||||
/** @var AccountRepositoryInterface $accountRepository */
|
||||
$accountRepository = app(AccountRepositoryInterface::class);
|
||||
$accounts = $accountRepository->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET, AccountType::CASH]);
|
||||
$return = [];
|
||||
/** @var Budget $budget */
|
||||
foreach ($budgets as $budget) {
|
||||
$budgetId = $budget->id;
|
||||
$return[$budgetId] = [
|
||||
'spent' => $this->spentInPeriod(new Collection([$budget]), $accounts, $start, $end),
|
||||
'budgeted' => '0',
|
||||
'currentRep' => false,
|
||||
];
|
||||
$budgetLimits = $this->getBudgetLimits($budget, $start, $end);
|
||||
$otherLimits = new Collection;
|
||||
|
||||
// get all the budget limits relevant between start and end and examine them:
|
||||
/** @var BudgetLimit $limit */
|
||||
foreach ($budgetLimits as $limit) {
|
||||
if ($limit->start_date->isSameDay($start) && $limit->end_date->isSameDay($end)
|
||||
) {
|
||||
$return[$budgetId]['currentLimit'] = $limit;
|
||||
$return[$budgetId]['budgeted'] = $limit->amount;
|
||||
continue;
|
||||
}
|
||||
// otherwise it's just one of the many relevant repetitions:
|
||||
$otherLimits->push($limit);
|
||||
}
|
||||
$return[$budgetId]['otherLimits'] = $otherLimits;
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param TransactionCurrency $currency
|
||||
* @param Carbon $start
|
||||
|
@@ -17,8 +17,8 @@ use Carbon\Carbon;
|
||||
use FireflyIII\Models\ExportJob;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Support\Str;
|
||||
use Storage;
|
||||
use Log;
|
||||
use Storage;
|
||||
|
||||
/**
|
||||
* Class ExportJobRepository
|
||||
|
@@ -14,6 +14,7 @@ namespace FireflyIII\Repositories\Journal;
|
||||
|
||||
use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Models\Category;
|
||||
use FireflyIII\Models\Note;
|
||||
use FireflyIII\Models\Tag;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
@@ -195,4 +196,31 @@ trait CreateJournalsTrait
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param TransactionJournal $journal
|
||||
* @param string $note
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function updateNote(TransactionJournal $journal, string $note): bool
|
||||
{
|
||||
if (strlen($note) === 0) {
|
||||
$dbNote = $journal->notes()->first();
|
||||
if (!is_null($dbNote)) {
|
||||
$dbNote->delete();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
$dbNote = $journal->notes()->first();
|
||||
if (is_null($dbNote)) {
|
||||
$dbNote = new Note();
|
||||
$dbNote->noteable()->associate($journal);
|
||||
}
|
||||
$dbNote->text = trim($note);
|
||||
$dbNote->save();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@@ -34,7 +34,7 @@ class JournalRepository implements JournalRepositoryInterface
|
||||
/** @var User */
|
||||
private $user;
|
||||
/** @var array */
|
||||
private $validMetaFields = ['interest_date', 'book_date', 'process_date', 'due_date', 'payment_date', 'invoice_date', 'internal_reference', 'notes'];
|
||||
private $validMetaFields = ['interest_date', 'book_date', 'process_date', 'due_date', 'payment_date', 'invoice_date', 'internal_reference'];
|
||||
|
||||
/**
|
||||
* @param TransactionJournal $journal
|
||||
@@ -235,6 +235,11 @@ class JournalRepository implements JournalRepositoryInterface
|
||||
$this->saveTags($journal, $data['tags']);
|
||||
}
|
||||
|
||||
// update note:
|
||||
if (isset($data['notes'])) {
|
||||
$this->updateNote($journal, $data['notes']);
|
||||
}
|
||||
|
||||
foreach ($data as $key => $value) {
|
||||
if (in_array($key, $this->validMetaFields)) {
|
||||
$journal->setMeta($key, $value);
|
||||
@@ -287,6 +292,11 @@ class JournalRepository implements JournalRepositoryInterface
|
||||
$this->updateTags($journal, $data['tags']);
|
||||
}
|
||||
|
||||
// update note:
|
||||
if (isset($data['notes'])) {
|
||||
$this->updateNote($journal, $data['notes']);
|
||||
}
|
||||
|
||||
// update meta fields:
|
||||
$result = $journal->save();
|
||||
if ($result) {
|
||||
@@ -324,6 +334,9 @@ class JournalRepository implements JournalRepositoryInterface
|
||||
$journal->categories()->detach();
|
||||
$journal->budgets()->detach();
|
||||
|
||||
// update note:
|
||||
$this->updateNote($journal, $data['notes']);
|
||||
|
||||
// update meta fields:
|
||||
$result = $journal->save();
|
||||
if ($result) {
|
||||
|
@@ -13,7 +13,6 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Repositories\PiggyBank;
|
||||
|
||||
use Amount;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Models\Note;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
@@ -240,12 +239,12 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
|
||||
*/
|
||||
public function getPiggyBanksWithAmount(): Collection
|
||||
{
|
||||
$currency = Amount::getDefaultCurrency();
|
||||
$currency = app('amount')->getDefaultCurrency();
|
||||
$set = $this->getPiggyBanks();
|
||||
foreach ($set as $piggy) {
|
||||
$currentAmount = $piggy->currentRelevantRep()->currentamount ?? '0';
|
||||
|
||||
$piggy->name = $piggy->name . ' (' . Amount::formatAnything($currency, $currentAmount, false) . ')';
|
||||
$piggy->name = $piggy->name . ' (' . app('amount')->formatAnything($currency, $currentAmount, false) . ')';
|
||||
}
|
||||
|
||||
return $set;
|
||||
|
@@ -349,7 +349,7 @@ class RuleRepository implements RuleRepositoryInterface
|
||||
{
|
||||
$order = 1;
|
||||
foreach ($data['rule-actions'] as $index => $action) {
|
||||
$value = $data['rule-action-values'][$index];
|
||||
$value = $data['rule-action-values'][$index] ?? '';
|
||||
$stopProcessing = isset($data['rule-action-stop'][$index]) ? true : false;
|
||||
|
||||
$actionValues = [
|
||||
|
@@ -187,6 +187,14 @@ class TagRepository implements TagRepositoryInterface
|
||||
return new Carbon;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Tag
|
||||
*/
|
||||
public function oldestTag(): ?Tag
|
||||
{
|
||||
return $this->user->tags()->whereNotNull('date')->orderBy('date', 'ASC')->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
*/
|
||||
@@ -330,7 +338,6 @@ class TagRepository implements TagRepositoryInterface
|
||||
Log::debug(sprintf('Found %d tags', $tags->count()));
|
||||
/** @var Tag $tag */
|
||||
foreach ($tags as $tag) {
|
||||
|
||||
$amount = floatval($this->sumOfTag($tag, null, null));
|
||||
$min = $amount < $min || is_null($min) ? $amount : $min;
|
||||
$max = $amount > $max ? $amount : $max;
|
||||
@@ -356,7 +363,6 @@ class TagRepository implements TagRepositoryInterface
|
||||
return $return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Tag $tag
|
||||
* @param array $data
|
||||
|
@@ -103,6 +103,11 @@ interface TagRepositoryInterface
|
||||
*/
|
||||
public function lastUseDate(Tag $tag): Carbon;
|
||||
|
||||
/**
|
||||
* @return Tag|null
|
||||
*/
|
||||
public function oldestTag(): ?Tag;
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
*/
|
||||
@@ -117,17 +122,6 @@ interface TagRepositoryInterface
|
||||
*/
|
||||
public function spentInPeriod(Tag $tag, Carbon $start, Carbon $end): string;
|
||||
|
||||
/**
|
||||
* Calculates various amounts in tag.
|
||||
*
|
||||
* @param Tag $tag
|
||||
* @param Carbon|null $start
|
||||
* @param Carbon|null $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function sumsOfTag(Tag $tag, ?Carbon $start, ?Carbon $end): array;
|
||||
|
||||
/**
|
||||
* This method stores a tag.
|
||||
*
|
||||
@@ -146,6 +140,17 @@ interface TagRepositoryInterface
|
||||
*/
|
||||
public function sumOfTag(Tag $tag, ?Carbon $start, ?Carbon $end): string;
|
||||
|
||||
/**
|
||||
* Calculates various amounts in tag.
|
||||
*
|
||||
* @param Tag $tag
|
||||
* @param Carbon|null $start
|
||||
* @param Carbon|null $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function sumsOfTag(Tag $tag, ?Carbon $start, ?Carbon $end): array;
|
||||
|
||||
/**
|
||||
* Generates a tag cloud.
|
||||
*
|
||||
|
@@ -40,15 +40,6 @@ abstract class BunqRequest
|
||||
'x-bunq-client-request-id' => 'X-Bunq-Client-Request-Id',
|
||||
];
|
||||
|
||||
/**
|
||||
* @return ServerPublicKey
|
||||
*/
|
||||
public function getServerPublicKey(): ServerPublicKey
|
||||
{
|
||||
return $this->serverPublicKey;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* BunqRequest constructor.
|
||||
*/
|
||||
@@ -70,6 +61,22 @@ abstract class BunqRequest
|
||||
return $this->server;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ServerPublicKey
|
||||
*/
|
||||
public function getServerPublicKey(): ServerPublicKey
|
||||
{
|
||||
return $this->serverPublicKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ServerPublicKey $serverPublicKey
|
||||
*/
|
||||
public function setServerPublicKey(ServerPublicKey $serverPublicKey)
|
||||
{
|
||||
$this->serverPublicKey = $serverPublicKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $privateKey
|
||||
*/
|
||||
@@ -86,14 +93,6 @@ abstract class BunqRequest
|
||||
$this->secret = $secret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ServerPublicKey $serverPublicKey
|
||||
*/
|
||||
public function setServerPublicKey(ServerPublicKey $serverPublicKey)
|
||||
{
|
||||
$this->serverPublicKey = $serverPublicKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $method
|
||||
* @param string $uri
|
||||
|
@@ -13,7 +13,6 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support;
|
||||
|
||||
use Amount as GlobalAmount;
|
||||
use Carbon\Carbon;
|
||||
use Crypt;
|
||||
use DB;
|
||||
@@ -51,7 +50,7 @@ class Steam
|
||||
$currencyId = intval($account->getMeta('currency_id'));
|
||||
// use system default currency:
|
||||
if ($currencyId === 0) {
|
||||
$currency = GlobalAmount::getDefaultCurrency();
|
||||
$currency = app('amount')->getDefaultCurrency();
|
||||
$currencyId = $currency->id;
|
||||
}
|
||||
// first part: get all balances in own currency:
|
||||
|
@@ -265,12 +265,12 @@ class AmountFormat extends Twig_Extension
|
||||
/**
|
||||
* @return Twig_SimpleFunction
|
||||
*/
|
||||
protected function journalTotalAmount(): Twig_SimpleFunction
|
||||
protected function journalAmount(): Twig_SimpleFunction
|
||||
{
|
||||
return new Twig_SimpleFunction(
|
||||
'journalTotalAmount', function (TransactionJournal $journal): string {
|
||||
'journalAmount', function (TransactionJournal $journal): string {
|
||||
|
||||
return app('amount')->journalTotalAmount($journal, true);
|
||||
return app('amount')->journalAmount($journal, true);
|
||||
}, ['is_safe' => ['html']]
|
||||
);
|
||||
}
|
||||
@@ -278,12 +278,12 @@ class AmountFormat extends Twig_Extension
|
||||
/**
|
||||
* @return Twig_SimpleFunction
|
||||
*/
|
||||
protected function journalAmount(): Twig_SimpleFunction
|
||||
protected function journalTotalAmount(): Twig_SimpleFunction
|
||||
{
|
||||
return new Twig_SimpleFunction(
|
||||
'journalAmount', function (TransactionJournal $journal): string {
|
||||
'journalTotalAmount', function (TransactionJournal $journal): string {
|
||||
|
||||
return app('amount')->journalAmount($journal, true);
|
||||
return app('amount')->journalTotalAmount($journal, true);
|
||||
}, ['is_safe' => ['html']]
|
||||
);
|
||||
}
|
||||
|
@@ -61,6 +61,6 @@ class AddTag implements ActionInterface
|
||||
|
||||
Log::debug(sprintf('RuleAction AddTag fired but tag %d ("%s") was already added to journal %d.', $tag->id, $tag->tag, $journal->id));
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
62
app/TransactionRules/Actions/AppendNotes.php
Normal file
62
app/TransactionRules/Actions/AppendNotes.php
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
/**
|
||||
* AppendNotes.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\TransactionRules\Actions;
|
||||
|
||||
use FireflyIII\Models\Note;
|
||||
use FireflyIII\Models\RuleAction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class AppendNotes
|
||||
*
|
||||
* @package FireflyIII\TransactionRules\Actions
|
||||
*/
|
||||
class AppendNotes implements ActionInterface
|
||||
{
|
||||
|
||||
private $action;
|
||||
|
||||
|
||||
/**
|
||||
* TriggerInterface constructor.
|
||||
*
|
||||
* @param RuleAction $action
|
||||
*/
|
||||
public function __construct(RuleAction $action)
|
||||
{
|
||||
$this->action = $action;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionJournal $journal
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function act(TransactionJournal $journal): bool
|
||||
{
|
||||
$dbNote = $journal->notes()->first();
|
||||
if (is_null($dbNote)) {
|
||||
$dbNote = new Note;
|
||||
$dbNote->noteable()->associate($journal);
|
||||
}
|
||||
$notes = $dbNote->text;
|
||||
Log::debug(sprintf('RuleAction AppendNotes appended "%s" to "%s".', $this->action->action_value, $notes));
|
||||
$notes = $notes . $this->action->action_value;
|
||||
$dbNote->text = $notes;
|
||||
$dbNote->save();
|
||||
$journal->save();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
57
app/TransactionRules/Actions/ClearNotes.php
Normal file
57
app/TransactionRules/Actions/ClearNotes.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
/**
|
||||
* ClearNotes.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\TransactionRules\Actions;
|
||||
|
||||
use FireflyIII\Models\Note;
|
||||
use FireflyIII\Models\RuleAction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class ClearNotes
|
||||
*
|
||||
* @package FireflyIII\TransactionRules\Actions
|
||||
*/
|
||||
class ClearNotes implements ActionInterface
|
||||
{
|
||||
|
||||
private $action;
|
||||
|
||||
|
||||
/**
|
||||
* TriggerInterface constructor.
|
||||
*
|
||||
* @param RuleAction $action
|
||||
*/
|
||||
public function __construct(RuleAction $action)
|
||||
{
|
||||
$this->action = $action;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionJournal $journal
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function act(TransactionJournal $journal): bool
|
||||
{
|
||||
Log::debug(sprintf('RuleAction ClearNotes removed all notes.'));
|
||||
$notes = $journal->notes()->get();
|
||||
/** @var Note $note */
|
||||
foreach ($notes as $note) {
|
||||
$note->delete();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
62
app/TransactionRules/Actions/PrependNotes.php
Normal file
62
app/TransactionRules/Actions/PrependNotes.php
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
/**
|
||||
* PrependNotes.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\TransactionRules\Actions;
|
||||
|
||||
use FireflyIII\Models\Note;
|
||||
use FireflyIII\Models\RuleAction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class PrependNotes
|
||||
*
|
||||
* @package FireflyIII\TransactionRules\Actions
|
||||
*/
|
||||
class PrependNotes implements ActionInterface
|
||||
{
|
||||
|
||||
private $action;
|
||||
|
||||
|
||||
/**
|
||||
* TriggerInterface constructor.
|
||||
*
|
||||
* @param RuleAction $action
|
||||
*/
|
||||
public function __construct(RuleAction $action)
|
||||
{
|
||||
$this->action = $action;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionJournal $journal
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function act(TransactionJournal $journal): bool
|
||||
{
|
||||
$dbNote = $journal->notes()->first();
|
||||
if (is_null($dbNote)) {
|
||||
$dbNote = new Note;
|
||||
$dbNote->noteable()->associate($journal);
|
||||
}
|
||||
$notes = $dbNote->text;
|
||||
Log::debug(sprintf('RuleAction PrependNotes prepended "%s" with "%s".', $notes, $this->action->action_value));
|
||||
$notes = $this->action->action_value . $notes;
|
||||
$dbNote->text = $notes;
|
||||
$dbNote->save();
|
||||
$journal->save();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@@ -46,7 +46,6 @@ class SetDescription implements ActionInterface
|
||||
public function act(TransactionJournal $journal): bool
|
||||
{
|
||||
$oldDescription = $journal->description;
|
||||
|
||||
$journal->description = $this->action->action_value;
|
||||
$journal->save();
|
||||
|
||||
|
@@ -66,7 +66,7 @@ class SetDestinationAccount implements ActionInterface
|
||||
if ($count > 2) {
|
||||
Log::error(sprintf('Cannot change destination account of journal #%d because it is a split journal.', $journal->id));
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// journal type:
|
||||
@@ -81,7 +81,7 @@ class SetDestinationAccount implements ActionInterface
|
||||
)
|
||||
);
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// if this is a withdrawal, the new destination account must be a expense account and may be created:
|
||||
|
62
app/TransactionRules/Actions/SetNotes.php
Normal file
62
app/TransactionRules/Actions/SetNotes.php
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
/**
|
||||
* SetNotes.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\TransactionRules\Actions;
|
||||
|
||||
use FireflyIII\Models\Note;
|
||||
use FireflyIII\Models\RuleAction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class SetNotes
|
||||
*
|
||||
* @package FireflyIII\TransactionRules\Actions
|
||||
*/
|
||||
class SetNotes implements ActionInterface
|
||||
{
|
||||
|
||||
private $action;
|
||||
|
||||
|
||||
/**
|
||||
* TriggerInterface constructor.
|
||||
*
|
||||
* @param RuleAction $action
|
||||
*/
|
||||
public function __construct(RuleAction $action)
|
||||
{
|
||||
$this->action = $action;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionJournal $journal
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function act(TransactionJournal $journal): bool
|
||||
{
|
||||
$dbNote = $journal->notes()->first();
|
||||
if (is_null($dbNote)) {
|
||||
$dbNote = new Note;
|
||||
$dbNote->noteable()->associate($journal);
|
||||
}
|
||||
$oldNotes = $dbNote->text;
|
||||
$dbNote->text = $this->action->action_value;
|
||||
$dbNote->save();
|
||||
$journal->save();
|
||||
|
||||
Log::debug(sprintf('RuleAction SetNotes changed the notes of journal #%d from "%s" to "%s".', $journal->id, $oldNotes, $this->action->action_value));
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@@ -66,7 +66,7 @@ class SetSourceAccount implements ActionInterface
|
||||
if ($count > 2) {
|
||||
Log::error(sprintf('Cannot change source account of journal #%d because it is a split journal.', $journal->id));
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// journal type:
|
||||
@@ -80,7 +80,7 @@ class SetSourceAccount implements ActionInterface
|
||||
)
|
||||
);
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// if this is a deposit, the new source account must be a revenue account and may be created:
|
||||
|
@@ -20,9 +20,10 @@ use FireflyIII\TransactionRules\Actions\ActionInterface;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Interface ActionInterface
|
||||
* @codeCoverageIgnore
|
||||
* Class ActionFactory
|
||||
*
|
||||
* @package FireflyIII\TransactionRules\Actions
|
||||
* @package FireflyIII\TransactionRules\Factory
|
||||
*/
|
||||
class ActionFactory
|
||||
{
|
||||
|
@@ -21,6 +21,7 @@ use FireflyIII\TransactionRules\Triggers\TriggerInterface;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
* Interface TriggerInterface
|
||||
*
|
||||
* @package FireflyIII\TransactionRules\Triggers
|
||||
|
@@ -38,6 +38,7 @@ class AbstractTrigger
|
||||
|
||||
/**
|
||||
* AbstractTrigger constructor.
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
private function __construct()
|
||||
{
|
||||
@@ -45,6 +46,7 @@ class AbstractTrigger
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
* @param string $triggerValue
|
||||
* @param bool $stopProcessing
|
||||
*
|
||||
@@ -60,6 +62,7 @@ class AbstractTrigger
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
* @param RuleTrigger $trigger
|
||||
*
|
||||
* @return AbstractTrigger
|
||||
@@ -74,21 +77,8 @@ class AbstractTrigger
|
||||
return $self;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param RuleTrigger $trigger
|
||||
* @param TransactionJournal $journal
|
||||
*/
|
||||
public static function makeFromTriggerAndJournal(RuleTrigger $trigger, TransactionJournal $journal)
|
||||
{
|
||||
$self = new static;
|
||||
$self->trigger = $trigger;
|
||||
$self->triggerValue = $trigger->trigger_value;
|
||||
$self->stopProcessing = $trigger->stop_processing;
|
||||
$self->journal = $journal;
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
* @param string $triggerValue
|
||||
*
|
||||
* @return AbstractTrigger
|
||||
@@ -102,6 +92,7 @@ class AbstractTrigger
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
* @return RuleTrigger
|
||||
*/
|
||||
public function getTrigger(): RuleTrigger
|
||||
@@ -110,6 +101,7 @@ class AbstractTrigger
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
* @return string
|
||||
*/
|
||||
public function getTriggerValue(): string
|
||||
|
@@ -66,10 +66,8 @@ final class DescriptionContains extends AbstractTrigger implements TriggerInterf
|
||||
{
|
||||
$search = strtolower($this->triggerValue);
|
||||
$source = strtolower($journal->description ?? '');
|
||||
|
||||
$strpos = strpos($source, $search);
|
||||
$strpos = stripos($source, $search);
|
||||
if (!($strpos === false)) {
|
||||
|
||||
Log::debug(sprintf('RuleTrigger DescriptionContains for journal #%d: "%s" contains "%s", return true.', $journal->id, $source, $search));
|
||||
|
||||
return true;
|
||||
|
@@ -69,10 +69,11 @@ final class DescriptionEnds extends AbstractTrigger implements TriggerInterface
|
||||
$searchLength = strlen($search);
|
||||
|
||||
// if the string to search for is longer than the description,
|
||||
// shorten the search string.
|
||||
// return false.
|
||||
if ($searchLength > $descriptionLength) {
|
||||
$search = substr($search, ($descriptionLength * -1));
|
||||
$searchLength = strlen($search);
|
||||
Log::debug(sprintf('RuleTrigger DescriptionEnds for journal #%d: "%s" does not end with "%s", return false.', $journal->id, $description, $search));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$part = substr($description, $searchLength * -1);
|
||||
|
@@ -75,10 +75,11 @@ final class FromAccountEnds extends AbstractTrigger implements TriggerInterface
|
||||
$searchLength = strlen($search);
|
||||
|
||||
// if the string to search for is longer than the account name,
|
||||
// shorten the search string.
|
||||
// it will never be in the account name.
|
||||
if ($searchLength > $nameLength) {
|
||||
$search = substr($search, ($nameLength * -1));
|
||||
$searchLength = strlen($search);
|
||||
Log::debug(sprintf('RuleTrigger FromAccountEnds for journal #%d: "%s" does not end with "%s", return false.', $journal->id, $name, $search));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -44,7 +44,12 @@ final class FromAccountIs extends AbstractTrigger implements TriggerInterface
|
||||
public static function willMatchEverything($value = null)
|
||||
{
|
||||
if (!is_null($value)) {
|
||||
return false;
|
||||
$res = strval($value) === '';
|
||||
if ($res === true) {
|
||||
Log::error(sprintf('Cannot use %s with "" as a value.', self::class));
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
Log::error(sprintf('Cannot use %s with a null value.', self::class));
|
||||
|
||||
|
@@ -12,6 +12,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\TransactionRules\Triggers;
|
||||
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Log;
|
||||
|
||||
@@ -57,6 +58,20 @@ final class HasAnyBudget extends AbstractTrigger implements TriggerInterface
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// perhaps transactions have budget?
|
||||
/** @var Transaction $transaction */
|
||||
foreach ($journal->transactions()->get() as $transaction) {
|
||||
$count = $transaction->budgets()->count();
|
||||
if ($count > 0) {
|
||||
Log::debug(
|
||||
sprintf('RuleTrigger HasAnyBudget for journal #%d (transaction #%d): count is %d, return true.', $journal->id, $transaction->id, $count)
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Log::debug(sprintf('RuleTrigger HasAnyBudget for journal #%d: count is %d, return false.', $journal->id, $count));
|
||||
|
||||
return false;
|
||||
|
@@ -12,6 +12,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\TransactionRules\Triggers;
|
||||
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Log;
|
||||
|
||||
@@ -57,6 +58,20 @@ final class HasAnyCategory extends AbstractTrigger implements TriggerInterface
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// perhaps transactions have category?
|
||||
/** @var Transaction $transaction */
|
||||
foreach ($journal->transactions()->get() as $transaction) {
|
||||
$count = $transaction->categories()->count();
|
||||
if ($count > 0) {
|
||||
Log::debug(
|
||||
sprintf('RuleTrigger HasAnyCategory for journal #%d (transaction #%d): count is %d, return true.', $journal->id, $transaction->id, $count)
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Log::debug(sprintf('RuleTrigger HasAnyCategory for journal #%d: count is %d, return false.', $journal->id, $count));
|
||||
|
||||
return false;
|
||||
|
@@ -13,6 +13,7 @@ namespace FireflyIII\TransactionRules\Triggers;
|
||||
|
||||
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Log;
|
||||
|
||||
class HasAttachment extends AbstractTrigger implements TriggerInterface
|
||||
{
|
||||
@@ -53,8 +54,15 @@ class HasAttachment extends AbstractTrigger implements TriggerInterface
|
||||
$minimum = intval($this->triggerValue);
|
||||
$attachments = $journal->attachments()->count();
|
||||
if ($attachments >= $minimum) {
|
||||
Log::debug(
|
||||
sprintf(
|
||||
'RuleTrigger HasAttachment for journal #%d: count is %d, is more than or equal to %d, return true.', $journal->id, $attachments, $minimum
|
||||
)
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
Log::debug(sprintf('RuleTrigger HasAttachment for journal #%d: count is %d, is less than %d, return true.', $journal->id, $attachments, $minimum));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@@ -12,6 +12,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\TransactionRules\Triggers;
|
||||
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Log;
|
||||
|
||||
@@ -52,11 +53,18 @@ final class HasNoBudget extends AbstractTrigger implements TriggerInterface
|
||||
public function triggered(TransactionJournal $journal): bool
|
||||
{
|
||||
$count = $journal->budgets()->count();
|
||||
|
||||
// perhaps transactions have budget?
|
||||
/** @var Transaction $transaction */
|
||||
foreach ($journal->transactions()->get() as $transaction) {
|
||||
$count += $transaction->budgets()->count();
|
||||
}
|
||||
if ($count === 0) {
|
||||
Log::debug(sprintf('RuleTrigger HasNoBudget for journal #%d: count is %d, return true.', $journal->id, $count));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Log::debug(sprintf('RuleTrigger HasNoBudget for journal #%d: count is %d, return false.', $journal->id, $count));
|
||||
|
||||
return false;
|
||||
|
@@ -12,6 +12,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\TransactionRules\Triggers;
|
||||
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Log;
|
||||
|
||||
@@ -52,6 +53,13 @@ final class HasNoCategory extends AbstractTrigger implements TriggerInterface
|
||||
public function triggered(TransactionJournal $journal): bool
|
||||
{
|
||||
$count = $journal->categories()->count();
|
||||
|
||||
// perhaps transactions have category?
|
||||
/** @var Transaction $transaction */
|
||||
foreach ($journal->transactions()->get() as $transaction) {
|
||||
$count += $transaction->categories()->count();
|
||||
}
|
||||
|
||||
if ($count === 0) {
|
||||
Log::debug(sprintf('RuleTrigger HasNoCategory for journal #%d: count is %d, return true.', $journal->id, $count));
|
||||
|
||||
|
73
app/TransactionRules/Triggers/NotesAny.php
Normal file
73
app/TransactionRules/Triggers/NotesAny.php
Normal file
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
/**
|
||||
* NotesAny.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\TransactionRules\Triggers;
|
||||
|
||||
use FireflyIII\Models\Note;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class NotesAny
|
||||
*
|
||||
* @package FireflyIII\TransactionRules\Triggers
|
||||
*/
|
||||
final class NotesAny extends AbstractTrigger implements TriggerInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* A trigger is said to "match anything", or match any given transaction,
|
||||
* when the trigger value is very vague or has no restrictions. Easy examples
|
||||
* are the "AmountMore"-trigger combined with an amount of 0: any given transaction
|
||||
* has an amount of more than zero! Other examples are all the "Description"-triggers
|
||||
* which have hard time handling empty trigger values such as "" or "*" (wild cards).
|
||||
*
|
||||
* If the user tries to create such a trigger, this method MUST return true so Firefly III
|
||||
* can stop the storing / updating the trigger. If the trigger is in any way restrictive
|
||||
* (even if it will still include 99.9% of the users transactions), this method MUST return
|
||||
* false.
|
||||
*
|
||||
* @param null $value
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function willMatchEverything($value = null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionJournal $journal
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function triggered(TransactionJournal $journal): bool
|
||||
{
|
||||
/** @var Note $note */
|
||||
$note = $journal->notes()->first();
|
||||
$text = '';
|
||||
if (!is_null($note)) {
|
||||
$text = $note->text;
|
||||
}
|
||||
|
||||
if (strlen($text) > 0) {
|
||||
|
||||
Log::debug(sprintf('RuleTrigger NotesEmpty for journal #%d: strlen > 0, return true.', $journal->id));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Log::debug(sprintf('RuleTrigger NotesEmpty for journal #%d: strlen is 0, return false.', $journal->id));
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
80
app/TransactionRules/Triggers/NotesAre.php
Normal file
80
app/TransactionRules/Triggers/NotesAre.php
Normal file
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
/**
|
||||
* NotesAre.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\TransactionRules\Triggers;
|
||||
|
||||
use FireflyIII\Models\Note;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class NotesAre
|
||||
*
|
||||
* @package FireflyIII\TransactionRules\Triggers
|
||||
*/
|
||||
final class NotesAre extends AbstractTrigger implements TriggerInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* A trigger is said to "match anything", or match any given transaction,
|
||||
* when the trigger value is very vague or has no restrictions. Easy examples
|
||||
* are the "AmountMore"-trigger combined with an amount of 0: any given transaction
|
||||
* has an amount of more than zero! Other examples are all the "Description"-triggers
|
||||
* which have hard time handling empty trigger values such as "" or "*" (wild cards).
|
||||
*
|
||||
* If the user tries to create such a trigger, this method MUST return true so Firefly III
|
||||
* can stop the storing / updating the trigger. If the trigger is in any way restrictive
|
||||
* (even if it will still include 99.9% of the users transactions), this method MUST return
|
||||
* false.
|
||||
*
|
||||
* @param null $value
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function willMatchEverything($value = null)
|
||||
{
|
||||
if (!is_null($value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Log::error(sprintf('Cannot use %s with a null value.', self::class));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionJournal $journal
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function triggered(TransactionJournal $journal): bool
|
||||
{
|
||||
/** @var Note $note */
|
||||
$note = $journal->notes()->first();
|
||||
$text = '';
|
||||
if (!is_null($note)) {
|
||||
$text = strtolower($note->text);
|
||||
}
|
||||
$search = strtolower($this->triggerValue);
|
||||
|
||||
if ($text === $search && strlen($text) > 0) {
|
||||
|
||||
Log::debug(sprintf('RuleTrigger NotesAre for journal #%d: "%s" is "%s", return true.', $journal->id, $text, $search));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Log::debug(sprintf('RuleTrigger NotesAre for journal #%d: "%s" is NOT "%s", return false.', $journal->id, $text, $search));
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
96
app/TransactionRules/Triggers/NotesContain.php
Normal file
96
app/TransactionRules/Triggers/NotesContain.php
Normal file
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
/**
|
||||
* NotesContain.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\TransactionRules\Triggers;
|
||||
|
||||
|
||||
use FireflyIII\Models\Note;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class NotesContain
|
||||
*
|
||||
* @package FireflyIII\TransactionRules\Triggers
|
||||
*/
|
||||
final class NotesContain extends AbstractTrigger implements TriggerInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* A trigger is said to "match anything", or match any given transaction,
|
||||
* when the trigger value is very vague or has no restrictions. Easy examples
|
||||
* are the "AmountMore"-trigger combined with an amount of 0: any given transaction
|
||||
* has an amount of more than zero! Other examples are all the "Description"-triggers
|
||||
* which have hard time handling empty trigger values such as "" or "*" (wild cards).
|
||||
*
|
||||
* If the user tries to create such a trigger, this method MUST return true so Firefly III
|
||||
* can stop the storing / updating the trigger. If the trigger is in any way restrictive
|
||||
* (even if it will still include 99.9% of the users transactions), this method MUST return
|
||||
* false.
|
||||
*
|
||||
* @param null $value
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function willMatchEverything($value = null)
|
||||
{
|
||||
if (!is_null($value)) {
|
||||
$res = strval($value) === '';
|
||||
if ($res === true) {
|
||||
Log::error(sprintf('Cannot use %s with "" as a value.', self::class));
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
Log::error(sprintf('Cannot use %s with a null value.', self::class));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionJournal $journal
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function triggered(TransactionJournal $journal): bool
|
||||
{
|
||||
$search = trim(strtolower($this->triggerValue));
|
||||
|
||||
if (strlen($search) === 0) {
|
||||
Log::debug(sprintf('RuleTrigger NotesContain for journal #%d: "%s" is empty, return false.', $journal->id, $search));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @var Note $note */
|
||||
$note = $journal->notes()->first();
|
||||
$text = '';
|
||||
if (!is_null($note)) {
|
||||
$text = strtolower($note->text);
|
||||
}
|
||||
|
||||
|
||||
$strpos = strpos($text, $search);
|
||||
if (!($strpos === false)) {
|
||||
|
||||
Log::debug(sprintf('RuleTrigger NotesContain for journal #%d: "%s" contains "%s", return true.', $journal->id, $text, $search));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Log::debug(sprintf('RuleTrigger NotesContain for journal #%d: "%s" does NOT contain "%s", return false.', $journal->id, $text, $search));
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
}
|
73
app/TransactionRules/Triggers/NotesEmpty.php
Normal file
73
app/TransactionRules/Triggers/NotesEmpty.php
Normal file
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
/**
|
||||
* NotesEmpty.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\TransactionRules\Triggers;
|
||||
|
||||
use FireflyIII\Models\Note;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class NotesEmpty
|
||||
*
|
||||
* @package FireflyIII\TransactionRules\Triggers
|
||||
*/
|
||||
final class NotesEmpty extends AbstractTrigger implements TriggerInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* A trigger is said to "match anything", or match any given transaction,
|
||||
* when the trigger value is very vague or has no restrictions. Easy examples
|
||||
* are the "AmountMore"-trigger combined with an amount of 0: any given transaction
|
||||
* has an amount of more than zero! Other examples are all the "Description"-triggers
|
||||
* which have hard time handling empty trigger values such as "" or "*" (wild cards).
|
||||
*
|
||||
* If the user tries to create such a trigger, this method MUST return true so Firefly III
|
||||
* can stop the storing / updating the trigger. If the trigger is in any way restrictive
|
||||
* (even if it will still include 99.9% of the users transactions), this method MUST return
|
||||
* false.
|
||||
*
|
||||
* @param null $value
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function willMatchEverything($value = null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionJournal $journal
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function triggered(TransactionJournal $journal): bool
|
||||
{
|
||||
/** @var Note $note */
|
||||
$note = $journal->notes()->first();
|
||||
$text = '';
|
||||
if (!is_null($note)) {
|
||||
$text = $note->text;
|
||||
}
|
||||
|
||||
if (strlen($text) === 0) {
|
||||
|
||||
Log::debug(sprintf('RuleTrigger NotesEmpty for journal #%d: strlen is 0, return true.', $journal->id));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Log::debug(sprintf('RuleTrigger NotesEmpty for journal #%d: strlen > 0, return false.', $journal->id));
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
97
app/TransactionRules/Triggers/NotesEnd.php
Normal file
97
app/TransactionRules/Triggers/NotesEnd.php
Normal file
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
/**
|
||||
* NotesEnd.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\TransactionRules\Triggers;
|
||||
|
||||
use FireflyIII\Models\Note;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class NotesEnd
|
||||
*
|
||||
* @package FireflyIII\TransactionRules\Triggers
|
||||
*/
|
||||
final class NotesEnd extends AbstractTrigger implements TriggerInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* A trigger is said to "match anything", or match any given transaction,
|
||||
* when the trigger value is very vague or has no restrictions. Easy examples
|
||||
* are the "AmountMore"-trigger combined with an amount of 0: any given transaction
|
||||
* has an amount of more than zero! Other examples are all the "Description"-triggers
|
||||
* which have hard time handling empty trigger values such as "" or "*" (wild cards).
|
||||
*
|
||||
* If the user tries to create such a trigger, this method MUST return true so Firefly III
|
||||
* can stop the storing / updating the trigger. If the trigger is in any way restrictive
|
||||
* (even if it will still include 99.9% of the users transactions), this method MUST return
|
||||
* false.
|
||||
*
|
||||
* @param null $value
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function willMatchEverything($value = null)
|
||||
{
|
||||
if (!is_null($value)) {
|
||||
$res = strval($value) === '';
|
||||
if ($res === true) {
|
||||
Log::error(sprintf('Cannot use %s with "" as a value.', self::class));
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
Log::error(sprintf('Cannot use %s with a null value.', self::class));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionJournal $journal
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function triggered(TransactionJournal $journal): bool
|
||||
{
|
||||
/** @var Note $note */
|
||||
$note = $journal->notes()->first();
|
||||
$text = '';
|
||||
if (!is_null($note)) {
|
||||
$text = strtolower($note->text);
|
||||
}
|
||||
$notesLength = strlen($text);
|
||||
$search = strtolower($this->triggerValue);
|
||||
$searchLength = strlen($search);
|
||||
|
||||
// if the string to search for is longer than the description,
|
||||
// return false
|
||||
if ($searchLength > $notesLength) {
|
||||
Log::debug(sprintf('RuleTrigger NotesEnd for journal #%d: "%s" does not end with "%s", return false.', $journal->id, $text, $search));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$part = substr($text, $searchLength * -1);
|
||||
|
||||
if ($part === $search) {
|
||||
|
||||
Log::debug(sprintf('RuleTrigger NotesEnd for journal #%d: "%s" ends with "%s", return true.', $journal->id, $text, $search));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Log::debug(sprintf('RuleTrigger NotesEnd for journal #%d: "%s" does not end with "%s", return false.', $journal->id, $text, $search));
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
88
app/TransactionRules/Triggers/NotesStart.php
Normal file
88
app/TransactionRules/Triggers/NotesStart.php
Normal file
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
/**
|
||||
* NotesStart.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\TransactionRules\Triggers;
|
||||
|
||||
|
||||
use FireflyIII\Models\Note;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class NotesStart
|
||||
*
|
||||
* @package FireflyIII\TransactionRules\Triggers
|
||||
*/
|
||||
final class NotesStart extends AbstractTrigger implements TriggerInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* A trigger is said to "match anything", or match any given transaction,
|
||||
* when the trigger value is very vague or has no restrictions. Easy examples
|
||||
* are the "AmountMore"-trigger combined with an amount of 0: any given transaction
|
||||
* has an amount of more than zero! Other examples are all the "Description"-triggers
|
||||
* which have hard time handling empty trigger values such as "" or "*" (wild cards).
|
||||
*
|
||||
* If the user tries to create such a trigger, this method MUST return true so Firefly III
|
||||
* can stop the storing / updating the trigger. If the trigger is in any way restrictive
|
||||
* (even if it will still include 99.9% of the users transactions), this method MUST return
|
||||
* false.
|
||||
*
|
||||
* @param null $value
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function willMatchEverything($value = null)
|
||||
{
|
||||
if (!is_null($value)) {
|
||||
$res = strval($value) === '';
|
||||
if ($res === true) {
|
||||
Log::error(sprintf('Cannot use %s with "" as a value.', self::class));
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
Log::error(sprintf('Cannot use %s with a null value.', self::class));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionJournal $journal
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function triggered(TransactionJournal $journal): bool
|
||||
{
|
||||
/** @var Note $note */
|
||||
$note = $journal->notes()->first();
|
||||
$text = '';
|
||||
if (!is_null($note)) {
|
||||
$text = strtolower($note->text);
|
||||
}
|
||||
$search = strtolower($this->triggerValue);
|
||||
|
||||
$part = substr($text, 0, strlen($search));
|
||||
|
||||
if ($part === $search) {
|
||||
Log::debug(sprintf('RuleTrigger NotesStart for journal #%d: "%s" starts with "%s", return true.', $journal->id, $text, $search));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Log::debug(sprintf('RuleTrigger NotesStart for journal #%d: "%s" does not start with "%s", return false.', $journal->id, $text, $search));
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
}
|
@@ -75,10 +75,11 @@ final class ToAccountEnds extends AbstractTrigger implements TriggerInterface
|
||||
$searchLength = strlen($search);
|
||||
|
||||
// if the string to search for is longer than the account name,
|
||||
// shorten the search string.
|
||||
// return false
|
||||
if ($searchLength > $toAccountNameLength) {
|
||||
$search = substr($search, ($toAccountNameLength * -1));
|
||||
$searchLength = strlen($search);
|
||||
Log::debug(sprintf('RuleTrigger ToAccountEnds for journal #%d: "%s" does not end with "%s", return false.', $journal->id, $toAccountName, $search));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -37,6 +37,7 @@ final class UserAction extends AbstractTrigger implements TriggerInterface
|
||||
* false.
|
||||
*
|
||||
* @param null $value
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
@@ -49,6 +50,7 @@ final class UserAction extends AbstractTrigger implements TriggerInterface
|
||||
* This trigger is always triggered, because the rule that it is a part of has been pre-selected on this condition.
|
||||
*
|
||||
* @param TransactionJournal $journal
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
|
@@ -47,24 +47,25 @@
|
||||
],
|
||||
"require": {
|
||||
"php": ">=7.1.0",
|
||||
"ext-intl": "*",
|
||||
"ext-bcmath": "*",
|
||||
"ext-mbstring": "*",
|
||||
"ext-curl": "*",
|
||||
"ext-intl": "*",
|
||||
"ext-mbstring": "*",
|
||||
"ext-zip": "*",
|
||||
"laravel/framework": "5.5.*",
|
||||
"davejamesmiller/laravel-breadcrumbs": "3.*",
|
||||
"watson/validating": "3.*",
|
||||
"doctrine/dbal": "^2.5",
|
||||
"league/commonmark": "0.15.*",
|
||||
"twig/twig": "1.30.0",
|
||||
"rcrowe/twigbridge": "0.9.*",
|
||||
"league/csv": "8.*",
|
||||
"laravelcollective/html": "^5.4",
|
||||
"rmccue/requests": "1.*",
|
||||
"pragmarx/google2fa": "1.*",
|
||||
"bacon/bacon-qr-code": "1.*",
|
||||
"fideloper/proxy": "~3.3"
|
||||
"davejamesmiller/laravel-breadcrumbs": "3.*",
|
||||
"doctrine/dbal": "^2.5",
|
||||
"fideloper/proxy": "~3.3",
|
||||
"laravel/framework": "5.5.*",
|
||||
"laravelcollective/html": "^5.4",
|
||||
"league/commonmark": "0.15.*",
|
||||
"league/csv": "8.*",
|
||||
"php-coveralls/php-coveralls": "^1.0",
|
||||
"pragmarx/google2fa": "1.*",
|
||||
"rcrowe/twigbridge": "0.9.*",
|
||||
"rmccue/requests": "1.*",
|
||||
"twig/twig": "1.30.0",
|
||||
"watson/validating": "3.*"
|
||||
},
|
||||
"require-dev": {
|
||||
"filp/whoops": "~2.0",
|
||||
|
560
composer.lock
generated
560
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"
|
||||
],
|
||||
"content-hash": "6ef9662416273714abd2652bbac20d4c",
|
||||
"content-hash": "deb789ede19ed07dba82e844171ae0e2",
|
||||
"packages": [
|
||||
{
|
||||
"name": "bacon/bacon-qr-code",
|
||||
@@ -783,17 +783,113 @@
|
||||
"time": "2017-06-15T17:19:42+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel/framework",
|
||||
"version": "v5.5.13",
|
||||
"name": "guzzle/guzzle",
|
||||
"version": "v3.9.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel/framework.git",
|
||||
"reference": "bfbe20d32ee9f98c89df852847827407a5127be4"
|
||||
"url": "https://github.com/guzzle/guzzle3.git",
|
||||
"reference": "0645b70d953bc1c067bbc8d5bc53194706b628d9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel/framework/zipball/bfbe20d32ee9f98c89df852847827407a5127be4",
|
||||
"reference": "bfbe20d32ee9f98c89df852847827407a5127be4",
|
||||
"url": "https://api.github.com/repos/guzzle/guzzle3/zipball/0645b70d953bc1c067bbc8d5bc53194706b628d9",
|
||||
"reference": "0645b70d953bc1c067bbc8d5bc53194706b628d9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-curl": "*",
|
||||
"php": ">=5.3.3",
|
||||
"symfony/event-dispatcher": "~2.1"
|
||||
},
|
||||
"replace": {
|
||||
"guzzle/batch": "self.version",
|
||||
"guzzle/cache": "self.version",
|
||||
"guzzle/common": "self.version",
|
||||
"guzzle/http": "self.version",
|
||||
"guzzle/inflection": "self.version",
|
||||
"guzzle/iterator": "self.version",
|
||||
"guzzle/log": "self.version",
|
||||
"guzzle/parser": "self.version",
|
||||
"guzzle/plugin": "self.version",
|
||||
"guzzle/plugin-async": "self.version",
|
||||
"guzzle/plugin-backoff": "self.version",
|
||||
"guzzle/plugin-cache": "self.version",
|
||||
"guzzle/plugin-cookie": "self.version",
|
||||
"guzzle/plugin-curlauth": "self.version",
|
||||
"guzzle/plugin-error-response": "self.version",
|
||||
"guzzle/plugin-history": "self.version",
|
||||
"guzzle/plugin-log": "self.version",
|
||||
"guzzle/plugin-md5": "self.version",
|
||||
"guzzle/plugin-mock": "self.version",
|
||||
"guzzle/plugin-oauth": "self.version",
|
||||
"guzzle/service": "self.version",
|
||||
"guzzle/stream": "self.version"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/cache": "~1.3",
|
||||
"monolog/monolog": "~1.0",
|
||||
"phpunit/phpunit": "3.7.*",
|
||||
"psr/log": "~1.0",
|
||||
"symfony/class-loader": "~2.1",
|
||||
"zendframework/zend-cache": "2.*,<2.3",
|
||||
"zendframework/zend-log": "2.*,<2.3"
|
||||
},
|
||||
"suggest": {
|
||||
"guzzlehttp/guzzle": "Guzzle 5 has moved to a new package name. The package you have installed, Guzzle 3, is deprecated."
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "3.9-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Guzzle": "src/",
|
||||
"Guzzle\\Tests": "tests/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Michael Dowling",
|
||||
"email": "mtdowling@gmail.com",
|
||||
"homepage": "https://github.com/mtdowling"
|
||||
},
|
||||
{
|
||||
"name": "Guzzle Community",
|
||||
"homepage": "https://github.com/guzzle/guzzle/contributors"
|
||||
}
|
||||
],
|
||||
"description": "PHP HTTP client. This library is deprecated in favor of https://packagist.org/packages/guzzlehttp/guzzle",
|
||||
"homepage": "http://guzzlephp.org/",
|
||||
"keywords": [
|
||||
"client",
|
||||
"curl",
|
||||
"framework",
|
||||
"http",
|
||||
"http client",
|
||||
"rest",
|
||||
"web service"
|
||||
],
|
||||
"abandoned": "guzzlehttp/guzzle",
|
||||
"time": "2015-03-18T18:23:50+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel/framework",
|
||||
"version": "v5.5.14",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel/framework.git",
|
||||
"reference": "26c700eb79e5bb55b59df2c495c9c71f16f43302"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel/framework/zipball/26c700eb79e5bb55b59df2c495c9c71f16f43302",
|
||||
"reference": "26c700eb79e5bb55b59df2c495c9c71f16f43302",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -912,7 +1008,7 @@
|
||||
"framework",
|
||||
"laravel"
|
||||
],
|
||||
"time": "2017-09-24T19:09:38+00:00"
|
||||
"time": "2017-10-03T17:41:03+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravelcollective/html",
|
||||
@@ -1411,6 +1507,64 @@
|
||||
],
|
||||
"time": "2017-09-27T21:40:39+00:00"
|
||||
},
|
||||
{
|
||||
"name": "php-coveralls/php-coveralls",
|
||||
"version": "v1.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-coveralls/php-coveralls.git",
|
||||
"reference": "da51d304fe8622bf9a6da39a8446e7afd432115c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-coveralls/php-coveralls/zipball/da51d304fe8622bf9a6da39a8446e7afd432115c",
|
||||
"reference": "da51d304fe8622bf9a6da39a8446e7afd432115c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"ext-simplexml": "*",
|
||||
"guzzle/guzzle": "^2.8|^3.0",
|
||||
"php": ">=5.3.3",
|
||||
"psr/log": "^1.0",
|
||||
"symfony/config": "^2.1|^3.0",
|
||||
"symfony/console": "^2.1|^3.0",
|
||||
"symfony/stopwatch": "^2.0|^3.0",
|
||||
"symfony/yaml": "^2.0|^3.0"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/http-kernel": "Allows Symfony integration"
|
||||
},
|
||||
"bin": [
|
||||
"bin/coveralls"
|
||||
],
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Satooshi\\": "src/Satooshi/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Kitamura Satoshi",
|
||||
"email": "with.no.parachute@gmail.com",
|
||||
"homepage": "https://www.facebook.com/satooshi.jp"
|
||||
}
|
||||
],
|
||||
"description": "PHP client library for Coveralls API",
|
||||
"homepage": "https://github.com/satooshi/php-coveralls",
|
||||
"keywords": [
|
||||
"ci",
|
||||
"coverage",
|
||||
"github",
|
||||
"test"
|
||||
],
|
||||
"time": "2016-01-20T17:35:46+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pragmarx/google2fa",
|
||||
"version": "v1.0.1",
|
||||
@@ -1813,16 +1967,16 @@
|
||||
},
|
||||
{
|
||||
"name": "swiftmailer/swiftmailer",
|
||||
"version": "v6.0.1",
|
||||
"version": "v6.0.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/swiftmailer/swiftmailer.git",
|
||||
"reference": "008f088d535ed3333af5ad804dd4c0eaf97c2805"
|
||||
"reference": "412333372fb6c8ffb65496a2bbd7321af75733fc"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/008f088d535ed3333af5ad804dd4c0eaf97c2805",
|
||||
"reference": "008f088d535ed3333af5ad804dd4c0eaf97c2805",
|
||||
"url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/412333372fb6c8ffb65496a2bbd7321af75733fc",
|
||||
"reference": "412333372fb6c8ffb65496a2bbd7321af75733fc",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1858,26 +2012,88 @@
|
||||
}
|
||||
],
|
||||
"description": "Swiftmailer, free feature-rich PHP mailer",
|
||||
"homepage": "http://swiftmailer.org",
|
||||
"homepage": "http://swiftmailer.symfony.com",
|
||||
"keywords": [
|
||||
"email",
|
||||
"mail",
|
||||
"mailer"
|
||||
],
|
||||
"time": "2017-05-20T06:20:27+00:00"
|
||||
"time": "2017-09-30T22:39:41+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
"version": "v3.3.9",
|
||||
"name": "symfony/config",
|
||||
"version": "v3.3.10",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/console.git",
|
||||
"reference": "a1e1b01293a090cb9ae2ddd221a3251a4a7e4abf"
|
||||
"url": "https://github.com/symfony/config.git",
|
||||
"reference": "4ab62407bff9cd97c410a7feaef04c375aaa5cfd"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/a1e1b01293a090cb9ae2ddd221a3251a4a7e4abf",
|
||||
"reference": "a1e1b01293a090cb9ae2ddd221a3251a4a7e4abf",
|
||||
"url": "https://api.github.com/repos/symfony/config/zipball/4ab62407bff9cd97c410a7feaef04c375aaa5cfd",
|
||||
"reference": "4ab62407bff9cd97c410a7feaef04c375aaa5cfd",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^5.5.9|>=7.0.8",
|
||||
"symfony/filesystem": "~2.8|~3.0"
|
||||
},
|
||||
"conflict": {
|
||||
"symfony/dependency-injection": "<3.3",
|
||||
"symfony/finder": "<3.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/dependency-injection": "~3.3",
|
||||
"symfony/finder": "~3.3",
|
||||
"symfony/yaml": "~3.0"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/yaml": "To use the yaml reference dumper"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "3.3-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Component\\Config\\": ""
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"/Tests/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony Config Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2017-10-04T18:56:58+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
"version": "v3.3.10",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/console.git",
|
||||
"reference": "116bc56e45a8e5572e51eb43ab58c769a352366c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/116bc56e45a8e5572e51eb43ab58c769a352366c",
|
||||
"reference": "116bc56e45a8e5572e51eb43ab58c769a352366c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1932,20 +2148,20 @@
|
||||
],
|
||||
"description": "Symfony Console Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2017-09-06T16:40:18+00:00"
|
||||
"time": "2017-10-02T06:42:24+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/css-selector",
|
||||
"version": "v3.3.9",
|
||||
"version": "v3.3.10",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/css-selector.git",
|
||||
"reference": "c5f5263ed231f164c58368efbce959137c7d9488"
|
||||
"reference": "07447650225ca9223bd5c97180fe7c8267f7d332"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/css-selector/zipball/c5f5263ed231f164c58368efbce959137c7d9488",
|
||||
"reference": "c5f5263ed231f164c58368efbce959137c7d9488",
|
||||
"url": "https://api.github.com/repos/symfony/css-selector/zipball/07447650225ca9223bd5c97180fe7c8267f7d332",
|
||||
"reference": "07447650225ca9223bd5c97180fe7c8267f7d332",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1985,20 +2201,20 @@
|
||||
],
|
||||
"description": "Symfony CssSelector Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2017-07-29T21:54:42+00:00"
|
||||
"time": "2017-10-02T06:42:24+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/debug",
|
||||
"version": "v3.3.9",
|
||||
"version": "v3.3.10",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/debug.git",
|
||||
"reference": "8beb24eec70b345c313640962df933499373a944"
|
||||
"reference": "eb95d9ce8f18dcc1b3dfff00cb624c402be78ffd"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/debug/zipball/8beb24eec70b345c313640962df933499373a944",
|
||||
"reference": "8beb24eec70b345c313640962df933499373a944",
|
||||
"url": "https://api.github.com/repos/symfony/debug/zipball/eb95d9ce8f18dcc1b3dfff00cb624c402be78ffd",
|
||||
"reference": "eb95d9ce8f18dcc1b3dfff00cb624c402be78ffd",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2041,34 +2257,31 @@
|
||||
],
|
||||
"description": "Symfony Debug Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2017-09-01T13:23:39+00:00"
|
||||
"time": "2017-10-02T06:42:24+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/event-dispatcher",
|
||||
"version": "v3.3.9",
|
||||
"version": "v2.8.28",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/event-dispatcher.git",
|
||||
"reference": "54ca9520a00386f83bca145819ad3b619aaa2485"
|
||||
"reference": "7fe089232554357efb8d4af65ce209fc6e5a2186"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/54ca9520a00386f83bca145819ad3b619aaa2485",
|
||||
"reference": "54ca9520a00386f83bca145819ad3b619aaa2485",
|
||||
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/7fe089232554357efb8d4af65ce209fc6e5a2186",
|
||||
"reference": "7fe089232554357efb8d4af65ce209fc6e5a2186",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^5.5.9|>=7.0.8"
|
||||
},
|
||||
"conflict": {
|
||||
"symfony/dependency-injection": "<3.3"
|
||||
"php": ">=5.3.9"
|
||||
},
|
||||
"require-dev": {
|
||||
"psr/log": "~1.0",
|
||||
"symfony/config": "~2.8|~3.0",
|
||||
"symfony/dependency-injection": "~3.3",
|
||||
"symfony/expression-language": "~2.8|~3.0",
|
||||
"symfony/stopwatch": "~2.8|~3.0"
|
||||
"symfony/config": "^2.0.5|~3.0.0",
|
||||
"symfony/dependency-injection": "~2.6|~3.0.0",
|
||||
"symfony/expression-language": "~2.6|~3.0.0",
|
||||
"symfony/stopwatch": "~2.3|~3.0.0"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/dependency-injection": "",
|
||||
@@ -2077,7 +2290,7 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "3.3-dev"
|
||||
"dev-master": "2.8-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@@ -2104,20 +2317,69 @@
|
||||
],
|
||||
"description": "Symfony EventDispatcher Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2017-07-29T21:54:42+00:00"
|
||||
"time": "2017-10-01T21:00:16+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/finder",
|
||||
"version": "v3.3.9",
|
||||
"name": "symfony/filesystem",
|
||||
"version": "v3.3.10",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/finder.git",
|
||||
"reference": "b2260dbc80f3c4198f903215f91a1ac7fe9fe09e"
|
||||
"url": "https://github.com/symfony/filesystem.git",
|
||||
"reference": "90bc45abf02ae6b7deb43895c1052cb0038506f1"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/finder/zipball/b2260dbc80f3c4198f903215f91a1ac7fe9fe09e",
|
||||
"reference": "b2260dbc80f3c4198f903215f91a1ac7fe9fe09e",
|
||||
"url": "https://api.github.com/repos/symfony/filesystem/zipball/90bc45abf02ae6b7deb43895c1052cb0038506f1",
|
||||
"reference": "90bc45abf02ae6b7deb43895c1052cb0038506f1",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^5.5.9|>=7.0.8"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "3.3-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Component\\Filesystem\\": ""
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"/Tests/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony Filesystem Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2017-10-03T13:33:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/finder",
|
||||
"version": "v3.3.10",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/finder.git",
|
||||
"reference": "773e19a491d97926f236942484cb541560ce862d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/finder/zipball/773e19a491d97926f236942484cb541560ce862d",
|
||||
"reference": "773e19a491d97926f236942484cb541560ce862d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2153,20 +2415,20 @@
|
||||
],
|
||||
"description": "Symfony Finder Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2017-07-29T21:54:42+00:00"
|
||||
"time": "2017-10-02T06:42:24+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/http-foundation",
|
||||
"version": "v3.3.9",
|
||||
"version": "v3.3.10",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/http-foundation.git",
|
||||
"reference": "2cdc7de1921d1a1c805a13dc05e44a2cd58f5ad3"
|
||||
"reference": "22cf9c2b1d9f67cc8e75ae7f4eaa60e4c1eff1f8"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/2cdc7de1921d1a1c805a13dc05e44a2cd58f5ad3",
|
||||
"reference": "2cdc7de1921d1a1c805a13dc05e44a2cd58f5ad3",
|
||||
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/22cf9c2b1d9f67cc8e75ae7f4eaa60e4c1eff1f8",
|
||||
"reference": "22cf9c2b1d9f67cc8e75ae7f4eaa60e4c1eff1f8",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2206,7 +2468,7 @@
|
||||
],
|
||||
"description": "Symfony HttpFoundation Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2017-09-06T17:07:39+00:00"
|
||||
"time": "2017-10-05T23:10:23+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/http-kernel",
|
||||
@@ -2462,16 +2724,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/process",
|
||||
"version": "v3.3.9",
|
||||
"version": "v3.3.10",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/process.git",
|
||||
"reference": "b7666e9b438027a1ea0e1ee813ec5042d5d7f6f0"
|
||||
"reference": "fdf89e57a723a29baf536e288d6e232c059697b1"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/process/zipball/b7666e9b438027a1ea0e1ee813ec5042d5d7f6f0",
|
||||
"reference": "b7666e9b438027a1ea0e1ee813ec5042d5d7f6f0",
|
||||
"url": "https://api.github.com/repos/symfony/process/zipball/fdf89e57a723a29baf536e288d6e232c059697b1",
|
||||
"reference": "fdf89e57a723a29baf536e288d6e232c059697b1",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2507,20 +2769,20 @@
|
||||
],
|
||||
"description": "Symfony Process Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2017-07-29T21:54:42+00:00"
|
||||
"time": "2017-10-02T06:42:24+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/routing",
|
||||
"version": "v3.3.9",
|
||||
"version": "v3.3.10",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/routing.git",
|
||||
"reference": "970326dcd04522e1cd1fe128abaee54c225e27f9"
|
||||
"reference": "2e26fa63da029dab49bf9377b3b4f60a8fecb009"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/routing/zipball/970326dcd04522e1cd1fe128abaee54c225e27f9",
|
||||
"reference": "970326dcd04522e1cd1fe128abaee54c225e27f9",
|
||||
"url": "https://api.github.com/repos/symfony/routing/zipball/2e26fa63da029dab49bf9377b3b4f60a8fecb009",
|
||||
"reference": "2e26fa63da029dab49bf9377b3b4f60a8fecb009",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2585,20 +2847,69 @@
|
||||
"uri",
|
||||
"url"
|
||||
],
|
||||
"time": "2017-07-29T21:54:42+00:00"
|
||||
"time": "2017-10-02T07:25:00+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/translation",
|
||||
"version": "v3.3.9",
|
||||
"name": "symfony/stopwatch",
|
||||
"version": "v3.3.10",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/translation.git",
|
||||
"reference": "add53753d978f635492dfe8cd6953f6a7361ef90"
|
||||
"url": "https://github.com/symfony/stopwatch.git",
|
||||
"reference": "170edf8b3247d7b6779eb6fa7428f342702ca184"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/translation/zipball/add53753d978f635492dfe8cd6953f6a7361ef90",
|
||||
"reference": "add53753d978f635492dfe8cd6953f6a7361ef90",
|
||||
"url": "https://api.github.com/repos/symfony/stopwatch/zipball/170edf8b3247d7b6779eb6fa7428f342702ca184",
|
||||
"reference": "170edf8b3247d7b6779eb6fa7428f342702ca184",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^5.5.9|>=7.0.8"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "3.3-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Component\\Stopwatch\\": ""
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"/Tests/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony Stopwatch Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2017-10-02T06:42:24+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/translation",
|
||||
"version": "v3.3.10",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/translation.git",
|
||||
"reference": "409bf229cd552bf7e3faa8ab7e3980b07672073f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/translation/zipball/409bf229cd552bf7e3faa8ab7e3980b07672073f",
|
||||
"reference": "409bf229cd552bf7e3faa8ab7e3980b07672073f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2650,20 +2961,20 @@
|
||||
],
|
||||
"description": "Symfony Translation Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2017-07-29T21:54:42+00:00"
|
||||
"time": "2017-10-02T06:42:24+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/var-dumper",
|
||||
"version": "v3.3.9",
|
||||
"version": "v3.3.10",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/var-dumper.git",
|
||||
"reference": "89fcb5a73e0ede2be2512234c4e40457bb22b35f"
|
||||
"reference": "03e3693a36701f1c581dd24a6d6eea2eba2113f6"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/89fcb5a73e0ede2be2512234c4e40457bb22b35f",
|
||||
"reference": "89fcb5a73e0ede2be2512234c4e40457bb22b35f",
|
||||
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/03e3693a36701f1c581dd24a6d6eea2eba2113f6",
|
||||
"reference": "03e3693a36701f1c581dd24a6d6eea2eba2113f6",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2718,7 +3029,62 @@
|
||||
"debug",
|
||||
"dump"
|
||||
],
|
||||
"time": "2017-08-27T14:52:21+00:00"
|
||||
"time": "2017-10-02T06:42:24+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/yaml",
|
||||
"version": "v3.3.10",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/yaml.git",
|
||||
"reference": "8c7bf1e7d5d6b05a690b715729cb4cd0c0a99c46"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/yaml/zipball/8c7bf1e7d5d6b05a690b715729cb4cd0c0a99c46",
|
||||
"reference": "8c7bf1e7d5d6b05a690b715729cb4cd0c0a99c46",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^5.5.9|>=7.0.8"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/console": "~2.8|~3.0"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/console": "For validating YAML files using the lint command"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "3.3-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Component\\Yaml\\": ""
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"/Tests/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony Yaml Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2017-10-05T14:43:42+00:00"
|
||||
},
|
||||
{
|
||||
"name": "tijsverkoyen/css-to-inline-styles",
|
||||
@@ -2880,16 +3246,16 @@
|
||||
},
|
||||
{
|
||||
"name": "watson/validating",
|
||||
"version": "3.0.2",
|
||||
"version": "3.1.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/dwightwatson/validating.git",
|
||||
"reference": "c6e9194b034a24d3b6e447bbc7a94d88fad9a1fd"
|
||||
"reference": "ade13078bf2e820e244603446114a28eda51b08c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/dwightwatson/validating/zipball/c6e9194b034a24d3b6e447bbc7a94d88fad9a1fd",
|
||||
"reference": "c6e9194b034a24d3b6e447bbc7a94d88fad9a1fd",
|
||||
"url": "https://api.github.com/repos/dwightwatson/validating/zipball/ade13078bf2e820e244603446114a28eda51b08c",
|
||||
"reference": "ade13078bf2e820e244603446114a28eda51b08c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2926,7 +3292,7 @@
|
||||
"laravel",
|
||||
"validation"
|
||||
],
|
||||
"time": "2017-08-25T02:12:38+00:00"
|
||||
"time": "2017-10-08T22:42:01+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [
|
||||
@@ -4042,16 +4408,16 @@
|
||||
},
|
||||
{
|
||||
"name": "phpunit/phpunit",
|
||||
"version": "6.3.1",
|
||||
"version": "6.4.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
||||
"reference": "c0ff817b36a827e64bf5f57bc72278150cf30a77"
|
||||
"reference": "b770d8ba7e60295ee91d69d5a5e01ae833cac220"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c0ff817b36a827e64bf5f57bc72278150cf30a77",
|
||||
"reference": "c0ff817b36a827e64bf5f57bc72278150cf30a77",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b770d8ba7e60295ee91d69d5a5e01ae833cac220",
|
||||
"reference": "b770d8ba7e60295ee91d69d5a5e01ae833cac220",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -4096,7 +4462,7 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "6.3.x-dev"
|
||||
"dev-master": "6.4.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@@ -4122,7 +4488,7 @@
|
||||
"testing",
|
||||
"xunit"
|
||||
],
|
||||
"time": "2017-09-24T07:25:54+00:00"
|
||||
"time": "2017-10-07T17:53:53+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/phpunit-mock-objects",
|
||||
@@ -4744,16 +5110,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/class-loader",
|
||||
"version": "v3.3.9",
|
||||
"version": "v3.3.10",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/class-loader.git",
|
||||
"reference": "9c69968ce57924e9e93550895cd2b0477edf0e19"
|
||||
"reference": "7572c904b209fa9907c69a6a9a68243c265a4d01"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/class-loader/zipball/9c69968ce57924e9e93550895cd2b0477edf0e19",
|
||||
"reference": "9c69968ce57924e9e93550895cd2b0477edf0e19",
|
||||
"url": "https://api.github.com/repos/symfony/class-loader/zipball/7572c904b209fa9907c69a6a9a68243c265a4d01",
|
||||
"reference": "7572c904b209fa9907c69a6a9a68243c265a4d01",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -4796,7 +5162,7 @@
|
||||
],
|
||||
"description": "Symfony ClassLoader Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2017-07-29T21:54:42+00:00"
|
||||
"time": "2017-10-02T06:42:24+00:00"
|
||||
},
|
||||
{
|
||||
"name": "theseer/tokenizer",
|
||||
@@ -4896,10 +5262,10 @@
|
||||
"prefer-lowest": false,
|
||||
"platform": {
|
||||
"php": ">=7.1.0",
|
||||
"ext-intl": "*",
|
||||
"ext-bcmath": "*",
|
||||
"ext-mbstring": "*",
|
||||
"ext-curl": "*",
|
||||
"ext-intl": "*",
|
||||
"ext-mbstring": "*",
|
||||
"ext-zip": "*"
|
||||
},
|
||||
"platform-dev": []
|
||||
|
@@ -21,6 +21,7 @@ return [
|
||||
'IngDescription' => 'FireflyIII\Import\Specifics\IngDescription',
|
||||
'RabobankDescription' => 'FireflyIII\Import\Specifics\RabobankDescription',
|
||||
'AbnAmroDescription' => 'FireflyIII\Import\Specifics\AbnAmroDescription',
|
||||
'SnsDescription' => 'FireflyIII\Import\Specifics\SnsDescription',
|
||||
'PresidentsChoice' => 'FireflyIII\Import\Specifics\PresidentsChoice',
|
||||
],
|
||||
|
||||
|
@@ -23,7 +23,7 @@ return [
|
||||
'is_demo_site' => false,
|
||||
],
|
||||
'encryption' => (is_null(env('USE_ENCRYPTION')) || env('USE_ENCRYPTION') === true),
|
||||
'version' => '4.6.6',
|
||||
'version' => '4.6.7',
|
||||
'maxUploadSize' => 15242880,
|
||||
'allowedMimes' => ['image/png', 'image/jpeg', 'application/pdf'],
|
||||
'list_length' => 10,
|
||||
@@ -117,7 +117,8 @@ return [
|
||||
'languages' => [
|
||||
'de_DE' => ['name_locale' => 'Deutsch', 'name_english' => 'German', 'complete' => true],
|
||||
'en_US' => ['name_locale' => 'English', 'name_english' => 'English', 'complete' => true],
|
||||
'fr_FR' => ['name_locale' => 'Français', 'name_english' => 'French', 'complete' => false],
|
||||
'fr_FR' => ['name_locale' => 'Français', 'name_english' => 'French', 'complete' => true],
|
||||
'id_ID' => ['name_locale' => 'Indonesian', 'name_english' => 'Indonesian', 'complete' => false],
|
||||
'nl_NL' => ['name_locale' => 'Nederlands', 'name_english' => 'Dutch', 'complete' => true],
|
||||
'pl_PL' => ['name_locale' => 'Polski', 'name_english' => 'Polish ', 'complete' => false],
|
||||
'pt_BR' => ['name_locale' => 'Português do Brasil', 'name_english' => 'Portuguese (Brazil)', 'complete' => true],
|
||||
@@ -200,6 +201,12 @@ return [
|
||||
'has_any_budget' => 'FireflyIII\TransactionRules\Triggers\HasAnyBudget',
|
||||
'has_no_tag' => 'FireflyIII\TransactionRules\Triggers\HasNoTag',
|
||||
'has_any_tag' => 'FireflyIII\TransactionRules\Triggers\HasAnyTag',
|
||||
'notes_contain' => 'FireflyIII\TransactionRules\Triggers\NotesContain',
|
||||
'notes_start' => 'FireflyIII\TransactionRules\Triggers\NotesStart',
|
||||
'notes_end' => 'FireflyIII\TransactionRules\Triggers\NotesEnd',
|
||||
'notes_are' => 'FireflyIII\TransactionRules\Triggers\NotesAre',
|
||||
'no_notes' => 'FireflyIII\TransactionRules\Triggers\NotesEmpty',
|
||||
'any_notes' => 'FireflyIII\TransactionRules\Triggers\NotesAny',
|
||||
],
|
||||
'rule-actions' => [
|
||||
'set_category' => 'FireflyIII\TransactionRules\Actions\SetCategory',
|
||||
@@ -212,9 +219,12 @@ return [
|
||||
'set_description' => 'FireflyIII\TransactionRules\Actions\SetDescription',
|
||||
'append_description' => 'FireflyIII\TransactionRules\Actions\AppendDescription',
|
||||
'prepend_description' => 'FireflyIII\TransactionRules\Actions\PrependDescription',
|
||||
|
||||
'set_source_account' => 'FireflyIII\TransactionRules\Actions\SetSourceAccount',
|
||||
'set_destination_account' => 'FireflyIII\TransactionRules\Actions\SetDestinationAccount',
|
||||
'set_notes' => 'FireflyIII\TransactionRules\Actions\SetNotes',
|
||||
'append_notes' => 'FireflyIII\TransactionRules\Actions\AppendNotes',
|
||||
'prepend_notes' => 'FireflyIII\TransactionRules\Actions\PrependNotes',
|
||||
'clear_notes' => 'FireflyIII\TransactionRules\Actions\ClearNotes',
|
||||
],
|
||||
'rule-actions-text' => [
|
||||
'set_category',
|
||||
|
40
phpunit.coverage.specific.xml
Normal file
40
phpunit.coverage.specific.xml
Normal file
@@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit backupGlobals="false"
|
||||
backupStaticAttributes="false"
|
||||
bootstrap="vendor/autoload.php"
|
||||
colors="true"
|
||||
convertErrorsToExceptions="true"
|
||||
convertNoticesToExceptions="true"
|
||||
convertWarningsToExceptions="true"
|
||||
processIsolation="false"
|
||||
stopOnFailure="true">
|
||||
<testsuites>
|
||||
<testsuite name="Feature">
|
||||
<directory suffix="Test.php">./tests/Feature</directory>
|
||||
</testsuite>
|
||||
|
||||
<testsuite name="Unit">
|
||||
<directory suffix="Test.php">./tests/Unit</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<filter>
|
||||
<whitelist processUncoveredFilesFromWhitelist="true">
|
||||
<directory suffix=".php">./app</directory>
|
||||
<exclude>
|
||||
<file>app/Http/breadcrumbs.php</file>
|
||||
</exclude>
|
||||
</whitelist>
|
||||
<blacklist>
|
||||
<directory>vendor/</directory>
|
||||
</blacklist>
|
||||
</filter>
|
||||
<logging>
|
||||
<log type="coverage-clover" target="./storage/build/clover-specific.xml" charset="UTF-8"/>
|
||||
</logging>
|
||||
<php>
|
||||
<env name="APP_ENV" value="testing"/>
|
||||
<env name="CACHE_DRIVER" value="array"/>
|
||||
<env name="SESSION_DRIVER" value="array"/>
|
||||
<env name="QUEUE_DRIVER" value="sync"/>
|
||||
</php>
|
||||
</phpunit>
|
49
phpunit.coverage.xml
Normal file
49
phpunit.coverage.xml
Normal file
@@ -0,0 +1,49 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ phpunit.coverage.xml
|
||||
~ Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
~ This software may be modified and distributed under the terms of the
|
||||
~ Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
~
|
||||
~ See the LICENSE file for details.
|
||||
-->
|
||||
|
||||
<phpunit backupGlobals="false"
|
||||
backupStaticAttributes="false"
|
||||
bootstrap="vendor/autoload.php"
|
||||
colors="true"
|
||||
convertErrorsToExceptions="true"
|
||||
convertNoticesToExceptions="true"
|
||||
convertWarningsToExceptions="true"
|
||||
processIsolation="false"
|
||||
stopOnFailure="true">
|
||||
<testsuites>
|
||||
<testsuite name="Feature">
|
||||
<directory suffix="Test.php">./tests/Feature</directory>
|
||||
</testsuite>
|
||||
|
||||
<testsuite name="Unit">
|
||||
<directory suffix="Test.php">./tests/Unit</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<filter>
|
||||
<whitelist processUncoveredFilesFromWhitelist="true">
|
||||
<directory suffix=".php">./app</directory>
|
||||
<exclude>
|
||||
<file>app/Http/breadcrumbs.php</file>
|
||||
</exclude>
|
||||
</whitelist>
|
||||
<blacklist>
|
||||
<directory>vendor/</directory>
|
||||
</blacklist>
|
||||
</filter>
|
||||
<logging>
|
||||
<log type="coverage-clover" target="./storage/build/clover-all.xml" charset="UTF-8"/>
|
||||
</logging>
|
||||
<php>
|
||||
<env name="APP_ENV" value="testing"/>
|
||||
<env name="CACHE_DRIVER" value="array"/>
|
||||
<env name="SESSION_DRIVER" value="array"/>
|
||||
<env name="QUEUE_DRIVER" value="sync"/>
|
||||
</php>
|
||||
</phpunit>
|
3
public/js/ff/rules/create-edit.js
vendored
3
public/js/ff/rules/create-edit.js
vendored
@@ -194,6 +194,7 @@ function updateActionInput(selectList) {
|
||||
break;
|
||||
case 'clear_category':
|
||||
case 'clear_budget':
|
||||
case 'clear_notes':
|
||||
case 'remove_all_tags':
|
||||
input.attr('disabled', 'disabled');
|
||||
break;
|
||||
@@ -265,6 +266,8 @@ function updateTriggerInput(selectList) {
|
||||
case 'has_no_budget':
|
||||
case 'has_any_budget':
|
||||
case 'has_no_tag':
|
||||
case 'no_notes':
|
||||
case 'any_notes':
|
||||
case 'has_any_tag':
|
||||
input.prop('disabled', true);
|
||||
input.typeahead('destroy');
|
||||
|
100
public/js/ff/tags/create-edit.js
vendored
100
public/js/ff/tags/create-edit.js
vendored
@@ -9,8 +9,6 @@
|
||||
|
||||
$(function () {
|
||||
"use strict";
|
||||
|
||||
$('#clearLocation').click(clearLocation);
|
||||
if (!Modernizr.inputtypes.date) {
|
||||
$('input[type="date"]').datepicker(
|
||||
{
|
||||
@@ -18,102 +16,4 @@ $(function () {
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
/*
|
||||
Some vars as prep for the map:
|
||||
*/
|
||||
var map;
|
||||
var markers = [];
|
||||
var setTag = false;
|
||||
|
||||
var mapOptions = {
|
||||
zoom: zoomLevel,
|
||||
center: new google.maps.LatLng(latitude, longitude),
|
||||
disableDefaultUI: true
|
||||
};
|
||||
|
||||
/*
|
||||
Clear location and reset zoomLevel.
|
||||
*/
|
||||
function clearLocation() {
|
||||
"use strict";
|
||||
deleteMarkers();
|
||||
$('input[name="latitude"]').val("");
|
||||
$('input[name="longitude"]').val("");
|
||||
$('input[name="zoomLevel"]').val("6");
|
||||
setTag = false;
|
||||
$('input[name="setTag"]').val('false');
|
||||
return false;
|
||||
}
|
||||
|
||||
function initialize() {
|
||||
"use strict";
|
||||
/*
|
||||
Create new map:
|
||||
*/
|
||||
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
|
||||
|
||||
/*
|
||||
Respond to click event.
|
||||
*/
|
||||
google.maps.event.addListener(map, 'rightclick', function (event) {
|
||||
placeMarker(event);
|
||||
});
|
||||
|
||||
/*
|
||||
Respond to zoom event.
|
||||
*/
|
||||
google.maps.event.addListener(map, 'zoom_changed', function () {
|
||||
saveZoomLevel();
|
||||
});
|
||||
/*
|
||||
Maybe place marker?
|
||||
*/
|
||||
if (doPlaceMarker === true) {
|
||||
var myLatlng = new google.maps.LatLng(latitude, longitude);
|
||||
var fakeEvent = {};
|
||||
fakeEvent.latLng = myLatlng;
|
||||
placeMarker(fakeEvent);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* save zoom level of map into hidden input.
|
||||
*/
|
||||
function saveZoomLevel() {
|
||||
"use strict";
|
||||
$('input[name="zoomLevel"]').val(map.getZoom());
|
||||
}
|
||||
|
||||
/**
|
||||
* Place marker on map.
|
||||
* @param event
|
||||
*/
|
||||
function placeMarker(event) {
|
||||
"use strict";
|
||||
deleteMarkers();
|
||||
var marker = new google.maps.Marker({position: event.latLng, map: map});
|
||||
$('input[name="latitude"]').val(event.latLng.lat());
|
||||
$('input[name="longitude"]').val(event.latLng.lng());
|
||||
markers.push(marker);
|
||||
setTag = true;
|
||||
$('input[name="setTag"]').val('true');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Deletes all markers in the array by removing references to them.
|
||||
*/
|
||||
function deleteMarkers() {
|
||||
"use strict";
|
||||
for (var i = 0; i < markers.length; i++) {
|
||||
markers[i].setMap(null);
|
||||
}
|
||||
markers = [];
|
||||
}
|
||||
|
||||
|
||||
google.maps.event.addDomListener(window, 'load', initialize);
|
39
public/js/ff/tags/show.js
vendored
39
public/js/ff/tags/show.js
vendored
@@ -11,34 +11,25 @@
|
||||
/*
|
||||
Some vars as prep for the map:
|
||||
*/
|
||||
var map;
|
||||
var setTag = false;
|
||||
|
||||
var mapOptions = {
|
||||
zoom: zoomLevel,
|
||||
center: new google.maps.LatLng(latitude, longitude),
|
||||
disableDefaultUI: true,
|
||||
zoomControl: false,
|
||||
scaleControl: true,
|
||||
draggable: false
|
||||
};
|
||||
|
||||
|
||||
function initialize() {
|
||||
$(function () {
|
||||
"use strict";
|
||||
if (doPlaceMarker === true) {
|
||||
/*
|
||||
Create new map:
|
||||
*/
|
||||
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
|
||||
|
||||
var myLatlng = new google.maps.LatLng(latitude, longitude);
|
||||
var marker = new google.maps.Marker({
|
||||
position: myLatlng,
|
||||
map: map
|
||||
// make map:
|
||||
var mymap = L.map('tag_location_map', {zoomControl: false, touchZoom: false, doubleClickZoom: false, scrollWheelZoom: false, boxZoom: false, dragging: false}).setView([latitude, longitude], zoomLevel);
|
||||
|
||||
L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', {
|
||||
attribution: 'Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="http://mapbox.com">Mapbox</a>',
|
||||
maxZoom: 18,
|
||||
id: 'mapbox.streets',
|
||||
accessToken: mapboxToken
|
||||
}).addTo(mymap);
|
||||
|
||||
if(doPlaceMarker) {
|
||||
var marker = L.marker([latitude, longitude]).addTo(mymap);
|
||||
}
|
||||
}
|
||||
});
|
||||
marker.setMap(map);
|
||||
}
|
||||
}
|
||||
|
||||
google.maps.event.addDomListener(window, 'load', initialize);
|
||||
|
5
public/js/ff/transactions/single/create.js
vendored
5
public/js/ff/transactions/single/create.js
vendored
@@ -72,9 +72,12 @@ function updateNativeCurrency(useAccountCurrency) {
|
||||
|
||||
$('.currency-option[data-id="' + nativeCurrencyId + '"]').click();
|
||||
$('[data-toggle="dropdown"]').parent().removeClass('open');
|
||||
if (what !== 'transfer') {
|
||||
if (what === 'withdrawal') {
|
||||
$('select[name="source_account_id"]').focus();
|
||||
}
|
||||
if (what === 'deposit') {
|
||||
$('select[name="destination_account_id"]').focus();
|
||||
}
|
||||
validateCurrencyForTransfer();
|
||||
}
|
||||
|
||||
|
BIN
public/lib/leaflet/images/layers-2x.png
Normal file
BIN
public/lib/leaflet/images/layers-2x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
BIN
public/lib/leaflet/images/layers.png
Normal file
BIN
public/lib/leaflet/images/layers.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 696 B |
BIN
public/lib/leaflet/images/marker-icon-2x.png
Normal file
BIN
public/lib/leaflet/images/marker-icon-2x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.5 KiB |
BIN
public/lib/leaflet/images/marker-icon.png
Normal file
BIN
public/lib/leaflet/images/marker-icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
BIN
public/lib/leaflet/images/marker-shadow.png
Normal file
BIN
public/lib/leaflet/images/marker-shadow.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 618 B |
13609
public/lib/leaflet/leaflet-src.js
vendored
Normal file
13609
public/lib/leaflet/leaflet-src.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
public/lib/leaflet/leaflet-src.js.map
Normal file
1
public/lib/leaflet/leaflet-src.js.map
Normal file
File diff suppressed because one or more lines are too long
632
public/lib/leaflet/leaflet.css
vendored
Normal file
632
public/lib/leaflet/leaflet.css
vendored
Normal file
@@ -0,0 +1,632 @@
|
||||
/* required styles */
|
||||
|
||||
.leaflet-pane,
|
||||
.leaflet-tile,
|
||||
.leaflet-marker-icon,
|
||||
.leaflet-marker-shadow,
|
||||
.leaflet-tile-container,
|
||||
.leaflet-pane > svg,
|
||||
.leaflet-pane > canvas,
|
||||
.leaflet-zoom-box,
|
||||
.leaflet-image-layer,
|
||||
.leaflet-layer {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
.leaflet-container {
|
||||
overflow: hidden;
|
||||
}
|
||||
.leaflet-tile,
|
||||
.leaflet-marker-icon,
|
||||
.leaflet-marker-shadow {
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
user-select: none;
|
||||
-webkit-user-drag: none;
|
||||
}
|
||||
/* Safari renders non-retina tile on retina better with this, but Chrome is worse */
|
||||
.leaflet-safari .leaflet-tile {
|
||||
image-rendering: -webkit-optimize-contrast;
|
||||
}
|
||||
/* hack that prevents hw layers "stretching" when loading new tiles */
|
||||
.leaflet-safari .leaflet-tile-container {
|
||||
width: 1600px;
|
||||
height: 1600px;
|
||||
-webkit-transform-origin: 0 0;
|
||||
}
|
||||
.leaflet-marker-icon,
|
||||
.leaflet-marker-shadow {
|
||||
display: block;
|
||||
}
|
||||
/* .leaflet-container svg: reset svg max-width decleration shipped in Joomla! (joomla.org) 3.x */
|
||||
/* .leaflet-container img: map is broken in FF if you have max-width: 100% on tiles */
|
||||
.leaflet-container .leaflet-overlay-pane svg,
|
||||
.leaflet-container .leaflet-marker-pane img,
|
||||
.leaflet-container .leaflet-shadow-pane img,
|
||||
.leaflet-container .leaflet-tile-pane img,
|
||||
.leaflet-container img.leaflet-image-layer {
|
||||
max-width: none !important;
|
||||
}
|
||||
|
||||
.leaflet-container.leaflet-touch-zoom {
|
||||
-ms-touch-action: pan-x pan-y;
|
||||
touch-action: pan-x pan-y;
|
||||
}
|
||||
.leaflet-container.leaflet-touch-drag {
|
||||
-ms-touch-action: pinch-zoom;
|
||||
}
|
||||
.leaflet-container.leaflet-touch-drag.leaflet-touch-zoom {
|
||||
-ms-touch-action: none;
|
||||
touch-action: none;
|
||||
}
|
||||
.leaflet-container {
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
.leaflet-container a {
|
||||
-webkit-tap-highlight-color: rgba(51, 181, 229, 0.4);
|
||||
}
|
||||
.leaflet-tile {
|
||||
filter: inherit;
|
||||
visibility: hidden;
|
||||
}
|
||||
.leaflet-tile-loaded {
|
||||
visibility: inherit;
|
||||
}
|
||||
.leaflet-zoom-box {
|
||||
width: 0;
|
||||
height: 0;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
z-index: 800;
|
||||
}
|
||||
/* workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=888319 */
|
||||
.leaflet-overlay-pane svg {
|
||||
-moz-user-select: none;
|
||||
}
|
||||
|
||||
.leaflet-pane { z-index: 400; }
|
||||
|
||||
.leaflet-tile-pane { z-index: 200; }
|
||||
.leaflet-overlay-pane { z-index: 400; }
|
||||
.leaflet-shadow-pane { z-index: 500; }
|
||||
.leaflet-marker-pane { z-index: 600; }
|
||||
.leaflet-tooltip-pane { z-index: 650; }
|
||||
.leaflet-popup-pane { z-index: 700; }
|
||||
|
||||
.leaflet-map-pane canvas { z-index: 100; }
|
||||
.leaflet-map-pane svg { z-index: 200; }
|
||||
|
||||
.leaflet-vml-shape {
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
}
|
||||
.lvml {
|
||||
behavior: url(#default#VML);
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
|
||||
/* control positioning */
|
||||
|
||||
.leaflet-control {
|
||||
position: relative;
|
||||
z-index: 800;
|
||||
pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
|
||||
pointer-events: auto;
|
||||
}
|
||||
.leaflet-top,
|
||||
.leaflet-bottom {
|
||||
position: absolute;
|
||||
z-index: 1000;
|
||||
pointer-events: none;
|
||||
}
|
||||
.leaflet-top {
|
||||
top: 0;
|
||||
}
|
||||
.leaflet-right {
|
||||
right: 0;
|
||||
}
|
||||
.leaflet-bottom {
|
||||
bottom: 0;
|
||||
}
|
||||
.leaflet-left {
|
||||
left: 0;
|
||||
}
|
||||
.leaflet-control {
|
||||
float: left;
|
||||
clear: both;
|
||||
}
|
||||
.leaflet-right .leaflet-control {
|
||||
float: right;
|
||||
}
|
||||
.leaflet-top .leaflet-control {
|
||||
margin-top: 10px;
|
||||
}
|
||||
.leaflet-bottom .leaflet-control {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.leaflet-left .leaflet-control {
|
||||
margin-left: 10px;
|
||||
}
|
||||
.leaflet-right .leaflet-control {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
|
||||
/* zoom and fade animations */
|
||||
|
||||
.leaflet-fade-anim .leaflet-tile {
|
||||
will-change: opacity;
|
||||
}
|
||||
.leaflet-fade-anim .leaflet-popup {
|
||||
opacity: 0;
|
||||
-webkit-transition: opacity 0.2s linear;
|
||||
-moz-transition: opacity 0.2s linear;
|
||||
-o-transition: opacity 0.2s linear;
|
||||
transition: opacity 0.2s linear;
|
||||
}
|
||||
.leaflet-fade-anim .leaflet-map-pane .leaflet-popup {
|
||||
opacity: 1;
|
||||
}
|
||||
.leaflet-zoom-animated {
|
||||
-webkit-transform-origin: 0 0;
|
||||
-ms-transform-origin: 0 0;
|
||||
transform-origin: 0 0;
|
||||
}
|
||||
.leaflet-zoom-anim .leaflet-zoom-animated {
|
||||
will-change: transform;
|
||||
}
|
||||
.leaflet-zoom-anim .leaflet-zoom-animated {
|
||||
-webkit-transition: -webkit-transform 0.25s cubic-bezier(0,0,0.25,1);
|
||||
-moz-transition: -moz-transform 0.25s cubic-bezier(0,0,0.25,1);
|
||||
-o-transition: -o-transform 0.25s cubic-bezier(0,0,0.25,1);
|
||||
transition: transform 0.25s cubic-bezier(0,0,0.25,1);
|
||||
}
|
||||
.leaflet-zoom-anim .leaflet-tile,
|
||||
.leaflet-pan-anim .leaflet-tile {
|
||||
-webkit-transition: none;
|
||||
-moz-transition: none;
|
||||
-o-transition: none;
|
||||
transition: none;
|
||||
}
|
||||
|
||||
.leaflet-zoom-anim .leaflet-zoom-hide {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
|
||||
/* cursors */
|
||||
|
||||
.leaflet-interactive {
|
||||
cursor: pointer;
|
||||
}
|
||||
.leaflet-grab {
|
||||
cursor: -webkit-grab;
|
||||
cursor: -moz-grab;
|
||||
}
|
||||
.leaflet-crosshair,
|
||||
.leaflet-crosshair .leaflet-interactive {
|
||||
cursor: crosshair;
|
||||
}
|
||||
.leaflet-popup-pane,
|
||||
.leaflet-control {
|
||||
cursor: auto;
|
||||
}
|
||||
.leaflet-dragging .leaflet-grab,
|
||||
.leaflet-dragging .leaflet-grab .leaflet-interactive,
|
||||
.leaflet-dragging .leaflet-marker-draggable {
|
||||
cursor: move;
|
||||
cursor: -webkit-grabbing;
|
||||
cursor: -moz-grabbing;
|
||||
}
|
||||
|
||||
/* marker & overlays interactivity */
|
||||
.leaflet-marker-icon,
|
||||
.leaflet-marker-shadow,
|
||||
.leaflet-image-layer,
|
||||
.leaflet-pane > svg path,
|
||||
.leaflet-tile-container {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.leaflet-marker-icon.leaflet-interactive,
|
||||
.leaflet-image-layer.leaflet-interactive,
|
||||
.leaflet-pane > svg path.leaflet-interactive {
|
||||
pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
/* visual tweaks */
|
||||
|
||||
.leaflet-container {
|
||||
background: #ddd;
|
||||
outline: 0;
|
||||
}
|
||||
.leaflet-container a {
|
||||
color: #0078A8;
|
||||
}
|
||||
.leaflet-container a.leaflet-active {
|
||||
outline: 2px solid orange;
|
||||
}
|
||||
.leaflet-zoom-box {
|
||||
border: 2px dotted #38f;
|
||||
background: rgba(255,255,255,0.5);
|
||||
}
|
||||
|
||||
|
||||
/* general typography */
|
||||
.leaflet-container {
|
||||
font: 12px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif;
|
||||
}
|
||||
|
||||
|
||||
/* general toolbar styles */
|
||||
|
||||
.leaflet-bar {
|
||||
box-shadow: 0 1px 5px rgba(0,0,0,0.65);
|
||||
border-radius: 4px;
|
||||
}
|
||||
.leaflet-bar a,
|
||||
.leaflet-bar a:hover {
|
||||
background-color: #fff;
|
||||
border-bottom: 1px solid #ccc;
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
line-height: 26px;
|
||||
display: block;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
color: black;
|
||||
}
|
||||
.leaflet-bar a,
|
||||
.leaflet-control-layers-toggle {
|
||||
background-position: 50% 50%;
|
||||
background-repeat: no-repeat;
|
||||
display: block;
|
||||
}
|
||||
.leaflet-bar a:hover {
|
||||
background-color: #f4f4f4;
|
||||
}
|
||||
.leaflet-bar a:first-child {
|
||||
border-top-left-radius: 4px;
|
||||
border-top-right-radius: 4px;
|
||||
}
|
||||
.leaflet-bar a:last-child {
|
||||
border-bottom-left-radius: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
border-bottom: none;
|
||||
}
|
||||
.leaflet-bar a.leaflet-disabled {
|
||||
cursor: default;
|
||||
background-color: #f4f4f4;
|
||||
color: #bbb;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-bar a {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
}
|
||||
.leaflet-touch .leaflet-bar a:first-child {
|
||||
border-top-left-radius: 2px;
|
||||
border-top-right-radius: 2px;
|
||||
}
|
||||
.leaflet-touch .leaflet-bar a:last-child {
|
||||
border-bottom-left-radius: 2px;
|
||||
border-bottom-right-radius: 2px;
|
||||
}
|
||||
|
||||
/* zoom control */
|
||||
|
||||
.leaflet-control-zoom-in,
|
||||
.leaflet-control-zoom-out {
|
||||
font: bold 18px 'Lucida Console', Monaco, monospace;
|
||||
text-indent: 1px;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-control-zoom-in, .leaflet-touch .leaflet-control-zoom-out {
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
|
||||
/* layers control */
|
||||
|
||||
.leaflet-control-layers {
|
||||
box-shadow: 0 1px 5px rgba(0,0,0,0.4);
|
||||
background: #fff;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.leaflet-control-layers-toggle {
|
||||
background-image: url(images/layers.png);
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
}
|
||||
.leaflet-retina .leaflet-control-layers-toggle {
|
||||
background-image: url(images/layers-2x.png);
|
||||
background-size: 26px 26px;
|
||||
}
|
||||
.leaflet-touch .leaflet-control-layers-toggle {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
}
|
||||
.leaflet-control-layers .leaflet-control-layers-list,
|
||||
.leaflet-control-layers-expanded .leaflet-control-layers-toggle {
|
||||
display: none;
|
||||
}
|
||||
.leaflet-control-layers-expanded .leaflet-control-layers-list {
|
||||
display: block;
|
||||
position: relative;
|
||||
}
|
||||
.leaflet-control-layers-expanded {
|
||||
padding: 6px 10px 6px 6px;
|
||||
color: #333;
|
||||
background: #fff;
|
||||
}
|
||||
.leaflet-control-layers-scrollbar {
|
||||
overflow-y: scroll;
|
||||
overflow-x: hidden;
|
||||
padding-right: 5px;
|
||||
}
|
||||
.leaflet-control-layers-selector {
|
||||
margin-top: 2px;
|
||||
position: relative;
|
||||
top: 1px;
|
||||
}
|
||||
.leaflet-control-layers label {
|
||||
display: block;
|
||||
}
|
||||
.leaflet-control-layers-separator {
|
||||
height: 0;
|
||||
border-top: 1px solid #ddd;
|
||||
margin: 5px -10px 5px -6px;
|
||||
}
|
||||
|
||||
/* Default icon URLs */
|
||||
.leaflet-default-icon-path {
|
||||
background-image: url(images/marker-icon.png);
|
||||
}
|
||||
|
||||
|
||||
/* attribution and scale controls */
|
||||
|
||||
.leaflet-container .leaflet-control-attribution {
|
||||
background: #fff;
|
||||
background: rgba(255, 255, 255, 0.7);
|
||||
margin: 0;
|
||||
}
|
||||
.leaflet-control-attribution,
|
||||
.leaflet-control-scale-line {
|
||||
padding: 0 5px;
|
||||
color: #333;
|
||||
}
|
||||
.leaflet-control-attribution a {
|
||||
text-decoration: none;
|
||||
}
|
||||
.leaflet-control-attribution a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.leaflet-container .leaflet-control-attribution,
|
||||
.leaflet-container .leaflet-control-scale {
|
||||
font-size: 11px;
|
||||
}
|
||||
.leaflet-left .leaflet-control-scale {
|
||||
margin-left: 5px;
|
||||
}
|
||||
.leaflet-bottom .leaflet-control-scale {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.leaflet-control-scale-line {
|
||||
border: 2px solid #777;
|
||||
border-top: none;
|
||||
line-height: 1.1;
|
||||
padding: 2px 5px 1px;
|
||||
font-size: 11px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
|
||||
background: #fff;
|
||||
background: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
.leaflet-control-scale-line:not(:first-child) {
|
||||
border-top: 2px solid #777;
|
||||
border-bottom: none;
|
||||
margin-top: -2px;
|
||||
}
|
||||
.leaflet-control-scale-line:not(:first-child):not(:last-child) {
|
||||
border-bottom: 2px solid #777;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-control-attribution,
|
||||
.leaflet-touch .leaflet-control-layers,
|
||||
.leaflet-touch .leaflet-bar {
|
||||
box-shadow: none;
|
||||
}
|
||||
.leaflet-touch .leaflet-control-layers,
|
||||
.leaflet-touch .leaflet-bar {
|
||||
border: 2px solid rgba(0,0,0,0.2);
|
||||
background-clip: padding-box;
|
||||
}
|
||||
|
||||
|
||||
/* popup */
|
||||
|
||||
.leaflet-popup {
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.leaflet-popup-content-wrapper {
|
||||
padding: 1px;
|
||||
text-align: left;
|
||||
border-radius: 12px;
|
||||
}
|
||||
.leaflet-popup-content {
|
||||
margin: 13px 19px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
.leaflet-popup-content p {
|
||||
margin: 18px 0;
|
||||
}
|
||||
.leaflet-popup-tip-container {
|
||||
width: 40px;
|
||||
height: 20px;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
margin-left: -20px;
|
||||
overflow: hidden;
|
||||
pointer-events: none;
|
||||
}
|
||||
.leaflet-popup-tip {
|
||||
width: 17px;
|
||||
height: 17px;
|
||||
padding: 1px;
|
||||
|
||||
margin: -10px auto 0;
|
||||
|
||||
-webkit-transform: rotate(45deg);
|
||||
-moz-transform: rotate(45deg);
|
||||
-ms-transform: rotate(45deg);
|
||||
-o-transform: rotate(45deg);
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
.leaflet-popup-content-wrapper,
|
||||
.leaflet-popup-tip {
|
||||
background: white;
|
||||
color: #333;
|
||||
box-shadow: 0 3px 14px rgba(0,0,0,0.4);
|
||||
}
|
||||
.leaflet-container a.leaflet-popup-close-button {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
padding: 4px 4px 0 0;
|
||||
border: none;
|
||||
text-align: center;
|
||||
width: 18px;
|
||||
height: 14px;
|
||||
font: 16px/14px Tahoma, Verdana, sans-serif;
|
||||
color: #c3c3c3;
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
background: transparent;
|
||||
}
|
||||
.leaflet-container a.leaflet-popup-close-button:hover {
|
||||
color: #999;
|
||||
}
|
||||
.leaflet-popup-scrolled {
|
||||
overflow: auto;
|
||||
border-bottom: 1px solid #ddd;
|
||||
border-top: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.leaflet-oldie .leaflet-popup-content-wrapper {
|
||||
zoom: 1;
|
||||
}
|
||||
.leaflet-oldie .leaflet-popup-tip {
|
||||
width: 24px;
|
||||
margin: 0 auto;
|
||||
|
||||
-ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)";
|
||||
filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678);
|
||||
}
|
||||
.leaflet-oldie .leaflet-popup-tip-container {
|
||||
margin-top: -1px;
|
||||
}
|
||||
|
||||
.leaflet-oldie .leaflet-control-zoom,
|
||||
.leaflet-oldie .leaflet-control-layers,
|
||||
.leaflet-oldie .leaflet-popup-content-wrapper,
|
||||
.leaflet-oldie .leaflet-popup-tip {
|
||||
border: 1px solid #999;
|
||||
}
|
||||
|
||||
|
||||
/* div icon */
|
||||
|
||||
.leaflet-div-icon {
|
||||
background: #fff;
|
||||
border: 1px solid #666;
|
||||
}
|
||||
|
||||
|
||||
/* Tooltip */
|
||||
/* Base styles for the element that has a tooltip */
|
||||
.leaflet-tooltip {
|
||||
position: absolute;
|
||||
padding: 6px;
|
||||
background-color: #fff;
|
||||
border: 1px solid #fff;
|
||||
border-radius: 3px;
|
||||
color: #222;
|
||||
white-space: nowrap;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
pointer-events: none;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.4);
|
||||
}
|
||||
.leaflet-tooltip.leaflet-clickable {
|
||||
cursor: pointer;
|
||||
pointer-events: auto;
|
||||
}
|
||||
.leaflet-tooltip-top:before,
|
||||
.leaflet-tooltip-bottom:before,
|
||||
.leaflet-tooltip-left:before,
|
||||
.leaflet-tooltip-right:before {
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
border: 6px solid transparent;
|
||||
background: transparent;
|
||||
content: "";
|
||||
}
|
||||
|
||||
/* Directions */
|
||||
|
||||
.leaflet-tooltip-bottom {
|
||||
margin-top: 6px;
|
||||
}
|
||||
.leaflet-tooltip-top {
|
||||
margin-top: -6px;
|
||||
}
|
||||
.leaflet-tooltip-bottom:before,
|
||||
.leaflet-tooltip-top:before {
|
||||
left: 50%;
|
||||
margin-left: -6px;
|
||||
}
|
||||
.leaflet-tooltip-top:before {
|
||||
bottom: 0;
|
||||
margin-bottom: -12px;
|
||||
border-top-color: #fff;
|
||||
}
|
||||
.leaflet-tooltip-bottom:before {
|
||||
top: 0;
|
||||
margin-top: -12px;
|
||||
margin-left: -6px;
|
||||
border-bottom-color: #fff;
|
||||
}
|
||||
.leaflet-tooltip-left {
|
||||
margin-left: -6px;
|
||||
}
|
||||
.leaflet-tooltip-right {
|
||||
margin-left: 6px;
|
||||
}
|
||||
.leaflet-tooltip-left:before,
|
||||
.leaflet-tooltip-right:before {
|
||||
top: 50%;
|
||||
margin-top: -6px;
|
||||
}
|
||||
.leaflet-tooltip-left:before {
|
||||
right: 0;
|
||||
margin-right: -12px;
|
||||
border-left-color: #fff;
|
||||
}
|
||||
.leaflet-tooltip-right:before {
|
||||
left: 0;
|
||||
margin-left: -12px;
|
||||
border-right-color: #fff;
|
||||
}
|
5
public/lib/leaflet/leaflet.js
vendored
Normal file
5
public/lib/leaflet/leaflet.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
public/lib/leaflet/leaflet.js.map
Normal file
1
public/lib/leaflet/leaflet.js.map
Normal file
File diff suppressed because one or more lines are too long
@@ -133,6 +133,7 @@ return [
|
||||
|
||||
// search
|
||||
'search' => 'Suche',
|
||||
'search_query' => 'Query',
|
||||
'search_found_transactions' => 'Anzahl der gefundenen Transaktionen:',
|
||||
'general_search_error' => 'Bei der Suche ist ein Fehler aufgetreten. Bitte überprüfen Sie die Protokolldateien für weitere Informationen.',
|
||||
'search_box' => 'Suche',
|
||||
@@ -292,6 +293,18 @@ return [
|
||||
'rule_trigger_has_no_tag' => 'Transaction has no tag(s)',
|
||||
'rule_trigger_has_any_tag_choice' => 'Has one or more (any) tags',
|
||||
'rule_trigger_has_any_tag' => 'Transaction has one or more (any) tags',
|
||||
'rule_trigger_any_notes_choice' => 'Has (any) notes',
|
||||
'rule_trigger_any_notes' => 'Transaction has (any) notes',
|
||||
'rule_trigger_no_notes_choice' => 'Has no notes',
|
||||
'rule_trigger_no_notes' => 'Transaction has no notes',
|
||||
'rule_trigger_notes_are_choice' => 'Notes are..',
|
||||
'rule_trigger_notes_are' => 'Notes are ":trigger_value"',
|
||||
'rule_trigger_notes_contain_choice' => 'Notes contain..',
|
||||
'rule_trigger_notes_contain' => 'Notes contain ":trigger_value"',
|
||||
'rule_trigger_notes_start_choice' => 'Notes start with..',
|
||||
'rule_trigger_notes_start' => 'Notes start with ":trigger_value"',
|
||||
'rule_trigger_notes_end_choice' => 'Notes end with..',
|
||||
'rule_trigger_notes_end' => 'Notes end with ":trigger_value"',
|
||||
'rule_action_set_category' => 'Kategorie zu ":action_value" festlegen',
|
||||
'rule_action_clear_category' => 'Bereinige Kategorie',
|
||||
'rule_action_set_budget' => 'Budget zu ":action_value" festlegen',
|
||||
@@ -316,6 +329,16 @@ return [
|
||||
'rule_action_set_source_account' => 'Lege Quellkonto als :action_value fest',
|
||||
'rule_action_set_destination_account_choice' => 'Zielkonto festlegen...',
|
||||
'rule_action_set_destination_account' => 'Lege Zielkonto als :action_value fest',
|
||||
'rule_action_append_notes_choice' => 'Append notes with..',
|
||||
'rule_action_append_notes' => 'Append notes with ":action_value"',
|
||||
'rule_action_prepend_notes_choice' => 'Prepend notes with..',
|
||||
'rule_action_prepend_notes' => 'Prepend notes with ":action_value"',
|
||||
'rule_action_clear_notes_choice' => 'Remove any notes',
|
||||
'rule_action_clear_notes' => 'Remove any notes',
|
||||
'rule_action_set_notes_choice' => 'Set notes to..',
|
||||
'rule_action_set_notes' => 'Set notes to ":action_value"',
|
||||
|
||||
|
||||
'rules_have_read_warning' => 'Have you read the warning?',
|
||||
'apply_rule_warning' => 'Warning: running a rule(group) on a large selection of transactions could take ages, and it could time-out. If it does, the rule(group) will only be applied to an unknown subset of your transactions. This might leave your financial administration in tatters. Please be careful.',
|
||||
|
||||
@@ -328,6 +351,8 @@ return [
|
||||
'without_date' => 'Ohne Datum',
|
||||
'result' => 'Ergebnis',
|
||||
'sums_apply_to_range' => 'All sums apply to the selected range',
|
||||
'press_tag_location' => 'Right click or long press to set the tag\'s location.',
|
||||
'clear_location' => 'Clear location',
|
||||
|
||||
// preferences
|
||||
'pref_home_screen_accounts' => 'Konten auf dem Startbildschirm',
|
||||
@@ -665,6 +690,8 @@ Sollen zusätzlich Ihre Girokonten angezeigt werden?',
|
||||
'newTransfer' => 'Neue Überweisung',
|
||||
'bills_to_pay' => 'Bills to pay',
|
||||
'per_day' => 'Per day',
|
||||
'left_to_spend_per_day' => 'Left to spend per day',
|
||||
'bills_paid' => 'Bills paid',
|
||||
|
||||
// menu and titles, should be recycled as often as possible:
|
||||
'currency' => 'Währung',
|
||||
@@ -944,6 +971,9 @@ Sollen zusätzlich Ihre Girokonten angezeigt werden?',
|
||||
'this_deposit' => 'This deposit',
|
||||
'this_transfer' => 'This transfer',
|
||||
'overview_for_link' => 'Overview for link type ":name"',
|
||||
'source_transaction' => 'Source transaction',
|
||||
'link_description' => 'Link description',
|
||||
'destination_transaction' => 'Destination transaction',
|
||||
'delete_journal_link' => 'Delete the link between <a href=":source_link">:source</a> and <a href=":destination_link">:destination</a>',
|
||||
'deleted_link' => 'Deleted link',
|
||||
|
||||
|
@@ -48,7 +48,7 @@ return [
|
||||
'budget_id' => 'Budget',
|
||||
'openingBalance' => 'Eröffnungsbilanz',
|
||||
'tagMode' => 'Tag-Modus',
|
||||
'tagPosition' => 'Ort des Tags',
|
||||
'tag_position' => 'Tag location',
|
||||
'virtualBalance' => 'Virtueller Kontostand',
|
||||
'targetamount' => 'Zielbetrag',
|
||||
'accountRole' => 'Rolle des Kontos',
|
||||
|
@@ -17,6 +17,7 @@ return [
|
||||
'id' => 'Id',
|
||||
'create_date' => 'Erstellt am',
|
||||
'update_date' => 'Aktualisiert am',
|
||||
'updated_at' => 'Updated at',
|
||||
'balance_before' => 'Bilanz vor',
|
||||
'balance_after' => 'Bilanz nach',
|
||||
'name' => 'Name',
|
||||
|
@@ -133,6 +133,7 @@ return [
|
||||
|
||||
// search
|
||||
'search' => 'Search',
|
||||
'search_query' => 'Query',
|
||||
'search_found_transactions' => 'Number of transactions found:',
|
||||
'general_search_error' => 'An error occured while searching. Please check the log files for more information.',
|
||||
'search_box' => 'Search',
|
||||
@@ -292,6 +293,18 @@ return [
|
||||
'rule_trigger_has_no_tag' => 'Transaction has no tag(s)',
|
||||
'rule_trigger_has_any_tag_choice' => 'Has one or more (any) tags',
|
||||
'rule_trigger_has_any_tag' => 'Transaction has one or more (any) tags',
|
||||
'rule_trigger_any_notes_choice' => 'Has (any) notes',
|
||||
'rule_trigger_any_notes' => 'Transaction has (any) notes',
|
||||
'rule_trigger_no_notes_choice' => 'Has no notes',
|
||||
'rule_trigger_no_notes' => 'Transaction has no notes',
|
||||
'rule_trigger_notes_are_choice' => 'Notes are..',
|
||||
'rule_trigger_notes_are' => 'Notes are ":trigger_value"',
|
||||
'rule_trigger_notes_contain_choice' => 'Notes contain..',
|
||||
'rule_trigger_notes_contain' => 'Notes contain ":trigger_value"',
|
||||
'rule_trigger_notes_start_choice' => 'Notes start with..',
|
||||
'rule_trigger_notes_start' => 'Notes start with ":trigger_value"',
|
||||
'rule_trigger_notes_end_choice' => 'Notes end with..',
|
||||
'rule_trigger_notes_end' => 'Notes end with ":trigger_value"',
|
||||
'rule_action_set_category' => 'Set category to ":action_value"',
|
||||
'rule_action_clear_category' => 'Clear category',
|
||||
'rule_action_set_budget' => 'Set budget to ":action_value"',
|
||||
@@ -316,6 +329,16 @@ return [
|
||||
'rule_action_set_source_account' => 'Set source account to :action_value',
|
||||
'rule_action_set_destination_account_choice' => 'Set destination account to...',
|
||||
'rule_action_set_destination_account' => 'Set destination account to :action_value',
|
||||
'rule_action_append_notes_choice' => 'Append notes with..',
|
||||
'rule_action_append_notes' => 'Append notes with ":action_value"',
|
||||
'rule_action_prepend_notes_choice' => 'Prepend notes with..',
|
||||
'rule_action_prepend_notes' => 'Prepend notes with ":action_value"',
|
||||
'rule_action_clear_notes_choice' => 'Remove any notes',
|
||||
'rule_action_clear_notes' => 'Remove any notes',
|
||||
'rule_action_set_notes_choice' => 'Set notes to..',
|
||||
'rule_action_set_notes' => 'Set notes to ":action_value"',
|
||||
|
||||
|
||||
'rules_have_read_warning' => 'Have you read the warning?',
|
||||
'apply_rule_warning' => 'Warning: running a rule(group) on a large selection of transactions could take ages, and it could time-out. If it does, the rule(group) will only be applied to an unknown subset of your transactions. This might leave your financial administration in tatters. Please be careful.',
|
||||
|
||||
@@ -328,6 +351,8 @@ return [
|
||||
'without_date' => 'Without date',
|
||||
'result' => 'Result',
|
||||
'sums_apply_to_range' => 'All sums apply to the selected range',
|
||||
'press_tag_location' => 'Right click or long press to set the tag\'s location.',
|
||||
'clear_location' => 'Clear location',
|
||||
|
||||
// preferences
|
||||
'pref_home_screen_accounts' => 'Home screen accounts',
|
||||
@@ -664,6 +689,8 @@ return [
|
||||
'newTransfer' => 'New transfer',
|
||||
'bills_to_pay' => 'Bills to pay',
|
||||
'per_day' => 'Per day',
|
||||
'left_to_spend_per_day' => 'Left to spend per day',
|
||||
'bills_paid' => 'Bills paid',
|
||||
|
||||
// menu and titles, should be recycled as often as possible:
|
||||
'currency' => 'Currency',
|
||||
@@ -943,6 +970,9 @@ return [
|
||||
'this_deposit' => 'This deposit',
|
||||
'this_transfer' => 'This transfer',
|
||||
'overview_for_link' => 'Overview for link type ":name"',
|
||||
'source_transaction' => 'Source transaction',
|
||||
'link_description' => 'Link description',
|
||||
'destination_transaction' => 'Destination transaction',
|
||||
'delete_journal_link' => 'Delete the link between <a href=":source_link">:source</a> and <a href=":destination_link">:destination</a>',
|
||||
'deleted_link' => 'Deleted link',
|
||||
|
||||
|
@@ -48,7 +48,7 @@ return [
|
||||
'budget_id' => 'Budget',
|
||||
'openingBalance' => 'Opening balance',
|
||||
'tagMode' => 'Tag mode',
|
||||
'tagPosition' => 'Tag location',
|
||||
'tag_position' => 'Tag location',
|
||||
'virtualBalance' => 'Virtual balance',
|
||||
'targetamount' => 'Target amount',
|
||||
'accountRole' => 'Account role',
|
||||
|
@@ -17,6 +17,7 @@ return [
|
||||
'id' => 'ID',
|
||||
'create_date' => 'Created at',
|
||||
'update_date' => 'Updated at',
|
||||
'updated_at' => 'Updated at',
|
||||
'balance_before' => 'Balance before',
|
||||
'balance_after' => 'Balance after',
|
||||
'name' => 'Name',
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user