Merge branch 'release/4.6.7'

This commit is contained in:
James Cole
2017-10-09 20:51:03 +02:00
215 changed files with 27228 additions and 5068 deletions

View File

@@ -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

View File

@@ -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:

View File

@@ -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.

View File

@@ -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

View File

@@ -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.}

View File

@@ -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.

View File

@@ -27,6 +27,7 @@ trait VerifiesAccessToken
{
/**
* Abstract method to make sure trait knows about method "option".
*
* @param null $key
*
* @return mixed

View File

@@ -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)
*/

View File

@@ -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,

View File

@@ -108,8 +108,8 @@ class ExpandedProcessor implements ProcessorInterface
$notes = $this->getNotes($ids);
$tags = $this->getTags($ids);
/** @var array $ibans */
$ibans = $this->getIbans($assetIds) + $this->getIbans($opposingIds);
$currencies = $this->getAccountCurrencies($ibans);
$ibans = $this->getIbans($assetIds) + $this->getIbans($opposingIds);
$currencies = $this->getAccountCurrencies($ibans);
$transactions->each(
function (Transaction $transaction) use ($notes, $tags, $ibans, $currencies) {
$journalId = intval($transaction->journal_id);

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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'));
}

View File

@@ -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;

View File

@@ -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);

View File

@@ -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);

View File

@@ -238,8 +238,8 @@ class CategoryController extends Controller
$subTitle = trans('firefly.all_journals_for_category', ['name' => $category->name]);
$first = $repository->firstUseDate($category);
/** @var Carbon $start */
$start = is_null($first) ? new Carbon : $first;
$end = new Carbon;
$start = is_null($first) ? new Carbon : $first;
$end = new Carbon;
}
// prep for "specific date" view.
@@ -257,7 +257,7 @@ class CategoryController extends Controller
// prep for current period
if (strlen($moment) === 0) {
/** @var Carbon $start */
$start = clone session('start', Navigation::startOfPeriod(new Carbon, $range));
$start = clone session('start', Navigation::startOfPeriod(new Carbon, $range));
/** @var Carbon $end */
$end = clone session('end', Navigation::endOfPeriod(new Carbon, $range));
$periods = $this->getPeriodOverview($category);

View File

@@ -44,7 +44,7 @@ class Controller extends BaseController
protected $monthAndDayFormat;
/** @var string */
protected $monthFormat;
/** @var string */
/** @var string */
protected $redirectUri = '/';
/**

View File

@@ -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();

View File

@@ -79,7 +79,7 @@ class BankController extends Controller
return redirect(route('import.bank.form', [$bank]));
}
$remoteAccounts = array_keys($remoteAccounts);
$class = config(sprintf('firefly.import_pre.%s', $bank));
$class = config(sprintf('firefly.import_pre.%s', $bank));
// get import file
// get import config

View File

@@ -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,

View File

@@ -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;

View File

@@ -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)]
)
)
);

View File

@@ -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);

View File

@@ -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 = clone(session('first'));
$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);

View File

@@ -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

View File

@@ -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);

View File

@@ -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);
}
}

View File

@@ -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 = [

View File

@@ -36,13 +36,14 @@ class Amount implements ConverterInterface
*/
public function convert($value): string
{
if(is_null($value)) {
if (is_null($value)) {
return '0';
}
$value = strval($value);
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 === '.') {

View 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;
}
}

View File

@@ -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));
}
// 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;
}
}
if ($hit === true) {
Log::error(
'There already is a transfer imported with these properties. Compare existing with new. ', ['existing' => $transfer, 'new' => $parameters]
);
}
return $hit;
return false;
}
}

View File

@@ -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

View File

@@ -130,17 +130,17 @@ class ExecuteRuleOnExistingTransactions extends Job implements ShouldQueue
// Lookup all journals that match the parameters specified
$transactions = $this->collectJournals();
$processor = Processor::make($this->rule, true);
$hits = 0;
$misses = 0;
$total = 0;
$hits = 0;
$misses = 0;
$total = 0;
// Execute the rules for each transaction
foreach ($transactions as $transaction) {
$total++;
$result = $processor->handleTransaction($transaction);
if($result) {
if ($result) {
$hits++;
}
if(!$result) {
if (!$result) {
$misses++;
}
Log::info(sprintf('Current progress: %d Transactions. Hits: %d, misses: %d', $total, $hits, $misses));

View File

@@ -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
{

View File

@@ -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()
{

View File

@@ -29,16 +29,16 @@ use Watson\Validating\ValidatingTrait;
* @property string $transaction_foreign_amount
* @property string $transaction_type_type
* @property string $foreign_currency_symbol
* @property int $foreign_currency_dp
* @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

View File

@@ -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

View File

@@ -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
*/

View File

@@ -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

View File

@@ -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

View File

@@ -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;
}
}

View File

@@ -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) {

View File

@@ -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;

View File

@@ -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 = [

View File

@@ -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

View File

@@ -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.
*

View File

@@ -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

View File

@@ -66,7 +66,7 @@ class BunqInformation implements InformationInterface
}
Log::debug('Now in getAccounts()');
$sessionToken = $this->startSession();
$userId = $this->getUserInformation($sessionToken);
$userId = $this->getUserInformation($sessionToken);
// get list of Bunq accounts:
$accounts = $this->getMonetaryAccounts($sessionToken, $userId);
$return = [];

View File

@@ -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:

View File

@@ -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']]
);
}

View File

@@ -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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View File

@@ -45,8 +45,7 @@ class SetDescription implements ActionInterface
*/
public function act(TransactionJournal $journal): bool
{
$oldDescription = $journal->description;
$oldDescription = $journal->description;
$journal->description = $this->action->action_value;
$journal->save();

View File

@@ -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:

View 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;
}
}

View File

@@ -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:

View File

@@ -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
{

View File

@@ -21,6 +21,7 @@ use FireflyIII\TransactionRules\Triggers\TriggerInterface;
use Log;
/**
* @codeCoverageIgnore
* Interface TriggerInterface
*
* @package FireflyIII\TransactionRules\Triggers

View File

@@ -40,7 +40,7 @@ final class Processor
public $rule;
/** @var Collection */
public $triggers;
/** @var int */
/** @var int */
protected $foundTriggers = 0;
/**

View File

@@ -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

View File

@@ -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;

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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));

View File

@@ -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;

View File

@@ -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;

View File

@@ -13,6 +13,7 @@ namespace FireflyIII\TransactionRules\Triggers;
use FireflyIII\Models\TransactionJournal;
use Log;
class HasAttachment extends AbstractTrigger implements TriggerInterface
{
@@ -50,11 +51,18 @@ class HasAttachment extends AbstractTrigger implements TriggerInterface
*/
public function triggered(TransactionJournal $journal): bool
{
$minimum = intval($this->triggerValue);
$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;
}

View File

@@ -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;

View File

@@ -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));

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View File

@@ -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;
}

View File

@@ -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
*/

View File

@@ -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
View File

@@ -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": []

View File

@@ -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',
],

View File

@@ -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,21 +201,30 @@ 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',
'clear_category' => 'FireflyIII\TransactionRules\Actions\ClearCategory',
'set_budget' => 'FireflyIII\TransactionRules\Actions\SetBudget',
'clear_budget' => 'FireflyIII\TransactionRules\Actions\ClearBudget',
'add_tag' => 'FireflyIII\TransactionRules\Actions\AddTag',
'remove_tag' => 'FireflyIII\TransactionRules\Actions\RemoveTag',
'remove_all_tags' => 'FireflyIII\TransactionRules\Actions\RemoveAllTags',
'set_description' => 'FireflyIII\TransactionRules\Actions\SetDescription',
'append_description' => 'FireflyIII\TransactionRules\Actions\AppendDescription',
'prepend_description' => 'FireflyIII\TransactionRules\Actions\PrependDescription',
'set_category' => 'FireflyIII\TransactionRules\Actions\SetCategory',
'clear_category' => 'FireflyIII\TransactionRules\Actions\ClearCategory',
'set_budget' => 'FireflyIII\TransactionRules\Actions\SetBudget',
'clear_budget' => 'FireflyIII\TransactionRules\Actions\ClearBudget',
'add_tag' => 'FireflyIII\TransactionRules\Actions\AddTag',
'remove_tag' => 'FireflyIII\TransactionRules\Actions\RemoveTag',
'remove_all_tags' => 'FireflyIII\TransactionRules\Actions\RemoveAllTags',
'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',

View 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
View 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>

View File

@@ -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');

View File

@@ -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);
});

View File

@@ -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
});
marker.setMap(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 &copy; <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);
}
}
}
google.maps.event.addDomListener(window, 'load', initialize);
});

View File

@@ -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();
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 696 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 618 B

13609
public/lib/leaflet/leaflet-src.js vendored Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

632
public/lib/leaflet/leaflet.css vendored Normal file
View 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

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More