Merge branch 'release/4.8.1.5'

This commit is contained in:
James Cole 2019-10-21 20:09:54 +02:00
commit 9f1fc0c2b8
151 changed files with 3072 additions and 1471 deletions

View File

@ -176,7 +176,6 @@ PUSHER_SECRET=
PUSHER_ID= PUSHER_ID=
DEMO_USERNAME= DEMO_USERNAME=
DEMO_PASSWORD= DEMO_PASSWORD=
IS_DOCKER=false
IS_SANDSTORM=false IS_SANDSTORM=false
IS_HEROKU=true IS_HEROKU=true
BUNQ_USE_SANDBOX=false BUNQ_USE_SANDBOX=false

View File

@ -171,7 +171,6 @@ PUSHER_SECRET=
PUSHER_ID= PUSHER_ID=
DEMO_USERNAME= DEMO_USERNAME=
DEMO_PASSWORD= DEMO_PASSWORD=
IS_DOCKER=false
IS_SANDSTORM=true IS_SANDSTORM=true
IS_HEROKU=false IS_HEROKU=false
BUNQ_USE_SANDBOX=false BUNQ_USE_SANDBOX=false

View File

@ -178,7 +178,6 @@ PUSHER_SECRET=
PUSHER_ID= PUSHER_ID=
DEMO_USERNAME= DEMO_USERNAME=
DEMO_PASSWORD= DEMO_PASSWORD=
IS_DOCKER=false
USE_ENCRYPTION=false USE_ENCRYPTION=false
IS_SANDSTORM=false IS_SANDSTORM=false
IS_HEROKU=false IS_HEROKU=false

2
.github/funding.yml vendored
View File

@ -1,5 +1,5 @@
# These are supported funding model platforms # These are supported funding model platforms
#github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] github: jc5
patreon: JC5 patreon: JC5
custom: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=44UKUT455HUFA custom: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=44UKUT455HUFA

View File

@ -1,7 +1,7 @@
sudo: required sudo: required
language: bash language: bash
env: env:
- VERSION=4.8.1.4 - VERSION=4.8.1.5
dist: xenial dist: xenial

View File

@ -1,4 +1,7 @@
FROM jc5x/firefly-iii-base-image:latest FROM jc5x/firefly-iii-base-image:latest
# See also: https://github.com/JC5/firefly-iii-base-image
ENV FIREFLY_PATH=/var/www/firefly-iii COMPOSER_ALLOW_SUPERUSER=1 ENV FIREFLY_PATH=/var/www/firefly-iii COMPOSER_ALLOW_SUPERUSER=1
LABEL version="1.5" maintainer="thegrumpydictator@gmail.com" LABEL version="1.5" maintainer="thegrumpydictator@gmail.com"

View File

@ -1,4 +1,7 @@
FROM jc5x/firefly-iii-base-image:latest FROM jc5x/firefly-iii-base-image:latest
# See also: https://github.com/JC5/firefly-iii-base-image
ENV FIREFLY_PATH=/var/www/firefly-iii COMPOSER_ALLOW_SUPERUSER=1 ENV FIREFLY_PATH=/var/www/firefly-iii COMPOSER_ALLOW_SUPERUSER=1
LABEL version="1.5" maintainer="thegrumpydictator@gmail.com" LABEL version="1.5" maintainer="thegrumpydictator@gmail.com"

View File

@ -1,4 +1,7 @@
FROM jc5x/firefly-iii-base-image:latest-arm FROM jc5x/firefly-iii-base-image:latest-arm
# See also: https://github.com/JC5/firefly-iii-base-image
ENV FIREFLY_PATH=/var/www/firefly-iii COMPOSER_ALLOW_SUPERUSER=1 ENV FIREFLY_PATH=/var/www/firefly-iii COMPOSER_ALLOW_SUPERUSER=1
LABEL version="1.5" maintainer="thegrumpydictator@gmail.com" LABEL version="1.5" maintainer="thegrumpydictator@gmail.com"

View File

@ -38,6 +38,7 @@ use Illuminate\Pagination\LengthAwarePaginator;
use League\Fractal\Pagination\IlluminatePaginatorAdapter; use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use League\Fractal\Resource\Collection as FractalCollection; use League\Fractal\Resource\Collection as FractalCollection;
use League\Fractal\Resource\Item; use League\Fractal\Resource\Item;
use Log;
use function strlen; use function strlen;
/** /**
@ -99,8 +100,14 @@ class AttachmentController extends Controller
if (false === $attachment->uploaded) { if (false === $attachment->uploaded) {
throw new FireflyException('No file has been uploaded for this attachment (yet).'); throw new FireflyException('No file has been uploaded for this attachment (yet).');
} }
if (0 === $attachment->size) {
throw new FireflyException('No file has been uploaded for this attachment (yet).');
}
if ($this->repository->exists($attachment)) { if ($this->repository->exists($attachment)) {
$content = $this->repository->getContent($attachment); $content = $this->repository->getContent($attachment);
if ('' === $content) {
throw new FireflyException('No file has been uploaded for this attachment (yet).');
}
$quoted = sprintf('"%s"', addcslashes(basename($attachment->filename), '"\\')); $quoted = sprintf('"%s"', addcslashes(basename($attachment->filename), '"\\'));
/** @var LaravelResponse $response */ /** @var LaravelResponse $response */
@ -233,6 +240,11 @@ class AttachmentController extends Controller
/** @var AttachmentHelperInterface $helper */ /** @var AttachmentHelperInterface $helper */
$helper = app(AttachmentHelperInterface::class); $helper = app(AttachmentHelperInterface::class);
$body = $request->getContent(); $body = $request->getContent();
if ('' === $body) {
Log::error('Body of attachment is empty.');
return response()->json([], 422);
}
$helper->saveAttachmentFromApi($attachment, $body); $helper->saveAttachmentFromApi($attachment, $body);
return response()->json([], 204); return response()->json([], 204);

View File

@ -83,7 +83,8 @@ class AccountController extends Controller
$transformer = app(AccountTransformer::class); $transformer = app(AccountTransformer::class);
$transformer->setParameters($this->parameters); $transformer->setParameters($this->parameters);
$count = $accounts->count(); $count = $accounts->count();
$paginator = new LengthAwarePaginator($accounts, $count, $count, 1); $perPage = 0 === $count ? 1 : $count;
$paginator = new LengthAwarePaginator($accounts, $count, $perPage, 1);
$resource = new FractalCollection($accounts, $transformer, 'accounts'); $resource = new FractalCollection($accounts, $transformer, 'accounts');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator)); $resource->setPaginator(new IlluminatePaginatorAdapter($paginator));

View File

@ -251,6 +251,19 @@ class TransactionController extends Controller
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
} }
/**
* Show a single transaction, by transaction journal.
*
* @param TransactionJournal $transactionJournal
*
* @return JsonResponse
* @codeCoverageIgnore
*/
public function showByJournal(TransactionJournal $transactionJournal): JsonResponse
{
return $this->show($transactionJournal->transactionGroup);
}
/** /**
* Store a new transaction. * Store a new transaction.
* *

View File

@ -74,7 +74,7 @@ class TransactionStoreRequest extends Request
{ {
$rules = [ $rules = [
// basic fields for group: // basic fields for group:
'group_title' => 'between:1,1000', 'group_title' => 'between:1,1000|nullable',
// transaction rules (in array for splits): // transaction rules (in array for splits):
'transactions.*.type' => 'required|in:withdrawal,deposit,transfer,opening-balance,reconciliation', 'transactions.*.type' => 'required|in:withdrawal,deposit,transfer,opening-balance,reconciliation',
@ -82,10 +82,10 @@ class TransactionStoreRequest extends Request
'transactions.*.order' => 'numeric|min:0', 'transactions.*.order' => 'numeric|min:0',
// currency info // currency info
'transactions.*.currency_id' => 'numeric|exists:transaction_currencies,id', 'transactions.*.currency_id' => 'numeric|exists:transaction_currencies,id|nullable',
'transactions.*.currency_code' => 'min:3|max:3|exists:transaction_currencies,code', 'transactions.*.currency_code' => 'min:3|max:3|exists:transaction_currencies,code|nullable',
'transactions.*.foreign_currency_id' => 'numeric|exists:transaction_currencies,id', 'transactions.*.foreign_currency_id' => 'numeric|exists:transaction_currencies,id|nullable',
'transactions.*.foreign_currency_code' => 'min:3|max:3|exists:transaction_currencies,code', 'transactions.*.foreign_currency_code' => 'min:3|max:3|exists:transaction_currencies,code|nullable',
// amount // amount
'transactions.*.amount' => 'required|numeric|more:0', 'transactions.*.amount' => 'required|numeric|more:0',
@ -97,10 +97,16 @@ class TransactionStoreRequest extends Request
// source of transaction // source of transaction
'transactions.*.source_id' => ['numeric', 'nullable', new BelongsUser], 'transactions.*.source_id' => ['numeric', 'nullable', new BelongsUser],
'transactions.*.source_name' => 'between:1,255|nullable', 'transactions.*.source_name' => 'between:1,255|nullable',
'transactions.*.source_iban' => 'between:1,255|nullable|iban',
'transactions.*.source_number' => 'between:1,255|nullable',
'transactions.*.source_bic' => 'between:1,255|nullable|bic',
// destination of transaction // destination of transaction
'transactions.*.destination_id' => ['numeric', 'nullable', new BelongsUser], 'transactions.*.destination_id' => ['numeric', 'nullable', new BelongsUser],
'transactions.*.destination_name' => 'between:1,255|nullable', 'transactions.*.destination_name' => 'between:1,255|nullable',
'transactions.*.destination_iban' => 'between:1,255|nullable|iban',
'transactions.*.destination_number' => 'between:1,255|nullable',
'transactions.*.destination_bic' => 'between:1,255|nullable|bic',
// budget, category, bill and piggy // budget, category, bill and piggy
'transactions.*.budget_id' => ['mustExist:budgets,id', new BelongsUser], 'transactions.*.budget_id' => ['mustExist:budgets,id', new BelongsUser],
@ -202,7 +208,7 @@ class TransactionStoreRequest extends Request
'date' => $this->dateFromValue($object['date']), 'date' => $this->dateFromValue($object['date']),
'order' => $this->integerFromValue((string)$object['order']), 'order' => $this->integerFromValue((string)$object['order']),
'currency_id' => $this->integerFromValue($object['currency_id']), 'currency_id' => $this->integerFromValue((string)$object['currency_id']),
'currency_code' => $this->stringFromValue($object['currency_code']), 'currency_code' => $this->stringFromValue($object['currency_code']),
// foreign currency info: // foreign currency info:
@ -219,10 +225,16 @@ class TransactionStoreRequest extends Request
// source of transaction. If everything is null, assume cash account. // source of transaction. If everything is null, assume cash account.
'source_id' => $this->integerFromValue((string)$object['source_id']), 'source_id' => $this->integerFromValue((string)$object['source_id']),
'source_name' => $this->stringFromValue($object['source_name']), 'source_name' => $this->stringFromValue($object['source_name']),
'source_iban' => $this->stringFromValue($object['source_iban']),
'source_number' => $this->stringFromValue($object['source_number']),
'source_bic' => $this->stringFromValue($object['source_bic']),
// destination of transaction. If everything is null, assume cash account. // destination of transaction. If everything is null, assume cash account.
'destination_id' => $this->integerFromValue((string)$object['destination_id']), 'destination_id' => $this->integerFromValue((string)$object['destination_id']),
'destination_name' => $this->stringFromValue($object['destination_name']), 'destination_name' => $this->stringFromValue($object['destination_name']),
'destination_iban' => $this->stringFromValue($object['destination_iban']),
'destination_number' => $this->stringFromValue($object['destination_number']),
'destination_bic' => $this->stringFromValue($object['destination_bic']),
// budget info // budget info
'budget_id' => $this->integerFromValue((string)$object['budget_id']), 'budget_id' => $this->integerFromValue((string)$object['budget_id']),

View File

@ -105,7 +105,13 @@ class TransactionUpdateRequest extends Request
'foreign_amount', 'foreign_amount',
'description', 'description',
'source_name', 'source_name',
'source_iban',
'source_number',
'source_bic',
'destination_name', 'destination_name',
'destination_iban',
'destination_number',
'destination_bic',
'budget_name', 'budget_name',
'category_name', 'category_name',
'bill_name', 'bill_name',

View File

@ -23,6 +23,7 @@ namespace FireflyIII\Console\Commands\Integrity;
use Artisan; use Artisan;
use Crypt; use Crypt;
use FireflyIII\Support\System\OAuthKeys;
use Illuminate\Console\Command; use Illuminate\Console\Command;
/** /**
@ -30,8 +31,6 @@ use Illuminate\Console\Command;
*/ */
class RestoreOAuthKeys extends Command class RestoreOAuthKeys extends Command
{ {
private const PRIVATE_KEY = 'oauth_private_key';
private const PUBLIC_KEY = 'oauth_public_key';
/** /**
* The console command description. * The console command description.
* *
@ -62,7 +61,7 @@ class RestoreOAuthKeys extends Command
*/ */
private function generateKeys(): void private function generateKeys(): void
{ {
Artisan::call('passport:keys'); OAuthKeys::generateKeys();
} }
/** /**
@ -70,7 +69,7 @@ class RestoreOAuthKeys extends Command
*/ */
private function keysInDatabase(): bool private function keysInDatabase(): bool
{ {
return app('fireflyconfig')->has(self::PRIVATE_KEY) && app('fireflyconfig')->has(self::PUBLIC_KEY); return OAuthKeys::keysInDatabase();
} }
/** /**
@ -78,10 +77,7 @@ class RestoreOAuthKeys extends Command
*/ */
private function keysOnDrive(): bool private function keysOnDrive(): bool
{ {
$private = storage_path('oauth-private.key'); return OAuthKeys::hasKeyFiles();
$public = storage_path('oauth-public.key');
return file_exists($private) && file_exists($public);
} }
/** /**
@ -89,12 +85,7 @@ class RestoreOAuthKeys extends Command
*/ */
private function restoreKeysFromDB(): void private function restoreKeysFromDB(): void
{ {
$privateContent = Crypt::decrypt(app('fireflyconfig')->get(self::PRIVATE_KEY)->data); OAuthKeys::restoreKeysFromDB();
$publicContent = Crypt::decrypt(app('fireflyconfig')->get(self::PUBLIC_KEY)->data);
$private = storage_path('oauth-private.key');
$public = storage_path('oauth-public.key');
file_put_contents($private, $privateContent);
file_put_contents($public, $publicContent);
} }
/** /**
@ -129,9 +120,6 @@ class RestoreOAuthKeys extends Command
*/ */
private function storeKeysInDB(): void private function storeKeysInDB(): void
{ {
$private = storage_path('oauth-private.key'); OAuthKeys::storeKeysInDB();
$public = storage_path('oauth-public.key');
app('fireflyconfig')->set(self::PRIVATE_KEY, Crypt::encrypt(file_get_contents($private)));
app('fireflyconfig')->set(self::PUBLIC_KEY, Crypt::encrypt(file_get_contents($public)));
} }
} }

View File

@ -68,7 +68,6 @@ class AccountMetaFactory
{ {
/** @var AccountMeta $entry */ /** @var AccountMeta $entry */
$entry = $account->accountMeta()->where('name', $field)->first(); $entry = $account->accountMeta()->where('name', $field)->first();
// must not be an empty string: // must not be an empty string:
if ('' !== $value) { if ('' !== $value) {

View File

@ -212,16 +212,33 @@ class TransactionJournalFactory
$carbon->setTimezone(config('app.timezone')); $carbon->setTimezone(config('app.timezone'));
/** Get source + destination account */ /** Get source + destination account */
Log::debug(sprintf('Source info: ID #%d, name "%s"', $row['source_id'], $row['source_name'])); Log::debug(sprintf('Currency is #%d (%s)', $currency->id, $currency->code));
Log::debug(sprintf('Destination info: ID #%d, name "%s"', $row['destination_id'], $row['destination_name']));
try { try {
// validate source and destination using a new Validator. // validate source and destination using a new Validator.
$this->validateAccounts($row); $this->validateAccounts($row);
/** create or get source and destination accounts */ /** create or get source and destination accounts */
$sourceAccount = $this->getAccount($type->type, 'source', (int)$row['source_id'], $row['source_name']);
$destinationAccount = $this->getAccount($type->type, 'destination', (int)$row['destination_id'], $row['destination_name']); $sourceInfo = [
'id' => (int)$row['source_id'],
'name' => $row['source_name'],
'iban' => $row['source_iban'],
'number' => $row['source_number'],
'bic' => $row['source_bic'],
];
$destInfo = [
'id' => (int)$row['destination_id'],
'name' => $row['destination_name'],
'iban' => $row['destination_iban'],
'number' => $row['destination_number'],
'bic' => $row['destination_bic'],
];
Log::debug('Source info:', $sourceInfo);
Log::debug('Destination info:', $destInfo);
$sourceAccount = $this->getAccount($type->type, 'source', $sourceInfo);
$destinationAccount = $this->getAccount($type->type, 'destination', $destInfo);
// @codeCoverageIgnoreStart // @codeCoverageIgnoreStart
} catch (FireflyException $e) { } catch (FireflyException $e) {
Log::error('Could not validate source or destination.'); Log::error('Could not validate source or destination.');
@ -372,8 +389,10 @@ class TransactionJournalFactory
// return user's default: // return user's default:
return app('amount')->getDefaultCurrencyByUser($this->user); return app('amount')->getDefaultCurrencyByUser($this->user);
} }
$result = $preference ?? $currency;
Log::debug(sprintf('Currency is now #%d (%s) because of account #%d (%s)', $result->id, $result->code, $account->id, $account->name));
return $preference ?? $currency; return $result;
} }
/** /**

View File

@ -162,6 +162,13 @@ class AttachmentHelper implements AttachmentHelperInterface
return false; return false;
// @codeCoverageIgnoreEnd // @codeCoverageIgnoreEnd
} }
if ('' === $content) {
Log::error('Cannot upload empty file.');
return false;
}
$path = stream_get_meta_data($resource)['uri']; $path = stream_get_meta_data($resource)['uri'];
fwrite($resource, $content); fwrite($resource, $content);
$finfo = finfo_open(FILEINFO_MIME_TYPE); $finfo = finfo_open(FILEINFO_MIME_TYPE);
@ -199,6 +206,7 @@ class AttachmentHelper implements AttachmentHelperInterface
if (!($model instanceof Model)) { if (!($model instanceof Model)) {
return false; // @codeCoverageIgnore return false; // @codeCoverageIgnore
} }
Log::debug(sprintf('Now in saveAttachmentsForModel for model %s', get_class($model))); Log::debug(sprintf('Now in saveAttachmentsForModel for model %s', get_class($model)));
if (is_array($files)) { if (is_array($files)) {
Log::debug('$files is an array.'); Log::debug('$files is an array.');
@ -362,6 +370,11 @@ class AttachmentHelper implements AttachmentHelperInterface
if (!$this->validMime($file)) { if (!$this->validMime($file)) {
$result = false; $result = false;
} }
if (0 === $file->getSize()) {
Log::error('Cannot upload empty file.');
$result = false;
}
// @codeCoverageIgnoreStart // @codeCoverageIgnoreStart
// can't seem to reach this point. // can't seem to reach this point.
if (true === $result && !$this->validSize($file)) { if (true === $result && !$this->validSize($file)) {

View File

@ -63,20 +63,19 @@ class IndexController extends Controller
} }
/** /**
* Show list of accounts.
*
* @param Request $request * @param Request $request
* @param string $objectType * @param string $objectType
* *
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/ */
public function index(Request $request, string $objectType) public function inactive(Request $request, string $objectType)
{ {
$objectType = $objectType ?? 'asset'; $objectType = $objectType ?? 'asset';
$subTitle = (string)trans(sprintf('firefly.%s_accounts', $objectType)); $inactivePage = true;
$subTitle = (string)trans(sprintf('firefly.%s_accounts_inactive', $objectType));
$subTitleIcon = config(sprintf('firefly.subIconsByIdentifier.%s', $objectType)); $subTitleIcon = config(sprintf('firefly.subIconsByIdentifier.%s', $objectType));
$types = config(sprintf('firefly.accountTypesByIdentifier.%s', $objectType)); $types = config(sprintf('firefly.accountTypesByIdentifier.%s', $objectType));
$collection = $this->repository->getAccountsByType($types); $collection = $this->repository->getInactiveAccountsByType($types);
$total = $collection->count(); $total = $collection->count();
$page = 0 === (int)$request->get('page') ? 1 : (int)$request->get('page'); $page = 0 === (int)$request->get('page') ? 1 : (int)$request->get('page');
$pageSize = (int)app('preferences')->get('listPageSize', 50)->data; $pageSize = (int)app('preferences')->get('listPageSize', 50)->data;
@ -105,11 +104,65 @@ class IndexController extends Controller
} }
); );
// make paginator:
$accounts = new LengthAwarePaginator($accounts, $total, $pageSize, $page);
$accounts->setPath(route('accounts.inactive.index', [$objectType]));
return view('accounts.index', compact('objectType','inactivePage', 'subTitleIcon', 'subTitle', 'page', 'accounts'));
}
/**
* Show list of accounts.
*
* @param Request $request
* @param string $objectType
*
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function index(Request $request, string $objectType)
{
$objectType = $objectType ?? 'asset';
$subTitle = (string)trans(sprintf('firefly.%s_accounts', $objectType));
$subTitleIcon = config(sprintf('firefly.subIconsByIdentifier.%s', $objectType));
$types = config(sprintf('firefly.accountTypesByIdentifier.%s', $objectType));
$collection = $this->repository->getActiveAccountsByType($types);
$total = $collection->count();
$page = 0 === (int)$request->get('page') ? 1 : (int)$request->get('page');
$pageSize = (int)app('preferences')->get('listPageSize', 50)->data;
$accounts = $collection->slice(($page - 1) * $pageSize, $pageSize);
$inactiveCount = $this->repository->getInactiveAccountsByType($types)->count();
unset($collection);
/** @var Carbon $start */
$start = clone session('start', Carbon::now()->startOfMonth());
/** @var Carbon $end */
$end = clone session('end', Carbon::now()->endOfMonth());
$start->subDay();
$ids = $accounts->pluck('id')->toArray();
$startBalances = app('steam')->balancesByAccounts($accounts, $start);
$endBalances = app('steam')->balancesByAccounts($accounts, $end);
$activities = app('steam')->getLastActivities($ids);
$accounts->each(
function (Account $account) use ($activities, $startBalances, $endBalances) {
$account->lastActivityDate = $this->isInArray($activities, $account->id);
$account->startBalance = $this->isInArray($startBalances, $account->id);
$account->endBalance = $this->isInArray($endBalances, $account->id);
$account->difference = bcsub($account->endBalance, $account->startBalance);
$account->interest = round($this->repository->getMetaValue($account, 'interest'), 6);
$account->interestPeriod = (string)trans(sprintf('firefly.interest_calc_%s', $this->repository->getMetaValue($account, 'interest_period')));
$account->accountTypeString = (string)trans(sprintf('firefly.account_type_%s', $account->accountType->type));
}
);
// make paginator: // make paginator:
$accounts = new LengthAwarePaginator($accounts, $total, $pageSize, $page); $accounts = new LengthAwarePaginator($accounts, $total, $pageSize, $page);
$accounts->setPath(route('accounts.index', [$objectType])); $accounts->setPath(route('accounts.index', [$objectType]));
return view('accounts.index', compact('objectType', 'subTitleIcon', 'subTitle', 'page', 'accounts')); return view('accounts.index', compact('objectType', 'inactiveCount', 'subTitleIcon', 'subTitle', 'page', 'accounts'));
} }

View File

@ -222,11 +222,11 @@ class AttachmentController extends Controller
"default-src 'none'", "default-src 'none'",
"object-src 'none'", "object-src 'none'",
"script-src 'none'", "script-src 'none'",
"style-src 'none'", "style-src 'self' 'unsafe-inline'",
"base-uri 'none'", "base-uri 'none'",
"font-src 'none'", "font-src 'none'",
"connect-src 'none'", "connect-src 'none'",
"img-src 'none'", "img-src 'self'",
"manifest-src 'none'", "manifest-src 'none'",
]; ];

View File

@ -127,7 +127,6 @@ class DebugController extends Controller
$currentDriver = DB::getDriverName(); $currentDriver = DB::getDriverName();
$userAgent = $request->header('user-agent'); $userAgent = $request->header('user-agent');
$isSandstorm = var_export(config('firefly.is_sandstorm'), true); $isSandstorm = var_export(config('firefly.is_sandstorm'), true);
$isDocker = var_export(config('firefly.is_docker'), true);
$toSandbox = var_export(config('firefly.bunq_use_sandbox'), true); $toSandbox = var_export(config('firefly.bunq_use_sandbox'), true);
$trustedProxies = config('firefly.trusted_proxies'); $trustedProxies = config('firefly.trusted_proxies');
$displayErrors = ini_get('display_errors'); $displayErrors = ini_get('display_errors');
@ -178,7 +177,7 @@ class DebugController extends Controller
'debug', compact( 'debug', compact(
'phpVersion', 'extensions', 'localeAttempts', 'appEnv', 'appDebug', 'logChannel', 'appLogLevel', 'now', 'drivers', 'phpVersion', 'extensions', 'localeAttempts', 'appEnv', 'appDebug', 'logChannel', 'appLogLevel', 'now', 'drivers',
'currentDriver', 'loginProvider', 'storageDisks', 'currentDriver', 'loginProvider', 'storageDisks',
'userAgent', 'displayErrors', 'errorReporting', 'phpOs', 'interface', 'logContent', 'cacheDriver', 'isDocker', 'isSandstorm', 'userAgent', 'displayErrors', 'errorReporting', 'phpOs', 'interface', 'logContent', 'cacheDriver', 'isSandstorm',
'trustedProxies', 'trustedProxies',
'toSandbox' 'toSandbox'
) )

View File

@ -113,6 +113,7 @@ class IntroController
} }
Log::debug(sprintf('Going to mark the following route as NOT done: %s with special "%s" (%s)', $route, $specialPage, $key)); Log::debug(sprintf('Going to mark the following route as NOT done: %s with special "%s" (%s)', $route, $specialPage, $key));
app('preferences')->set($key, false); app('preferences')->set($key, false);
app('preferences')->mark();
return response()->json(['message' => (string)trans('firefly.intro_boxes_after_refresh')]); return response()->json(['message' => (string)trans('firefly.intro_boxes_after_refresh')]);
} }

View File

@ -289,8 +289,8 @@ class BudgetController extends Controller
// loop again to get percentages. // loop again to get percentages.
foreach ($report as $budgetId => $data) { foreach ($report as $budgetId => $data) {
foreach ($data['currencies'] as $currencyId => $data) { foreach ($data['currencies'] as $currencyId => $dataX) {
$sum = $data['sum'] ?? '0'; $sum = $dataX['sum'] ?? '0';
$total = $sums[$currencyId]['sum'] ?? '0'; $total = $sums[$currencyId]['sum'] ?? '0';
$pct = '0'; $pct = '0';
if (0 !== bccomp($sum, '0') && 0 !== bccomp($total, '9')) { if (0 !== bccomp($sum, '0') && 0 !== bccomp($total, '9')) {
@ -361,7 +361,8 @@ class BudgetController extends Controller
]; ];
// make sum information: // make sum information:
$report['sums'][$currency->id] = $report['sums'][$currency->id] ?? [ $report['sums'][$currency->id]
= $report['sums'][$currency->id] ?? [
'budgeted' => '0', 'budgeted' => '0',
'spent' => '0', 'spent' => '0',
'left' => '0', 'left' => '0',
@ -411,15 +412,13 @@ class BudgetController extends Controller
// make percentages based on total amount. // make percentages based on total amount.
foreach ($report['budgets'] as $budgetId => $data) { foreach ($report['budgets'] as $budgetId => $data) {
foreach ($data['budget_limits'] as $limitId => $entry) { foreach ($data['budget_limits'] as $limitId => $entry) {
$currencyId = $entry['currency_id']; $currencyId = $entry['currency_id'];
$spent = $entry['spent'];
$spent = $entry['spent']; $totalSpent = $report['sums'][$currencyId]['spent'] ?? '0';
$totalSpent = $report['sums'][$currencyId]['spent'] ?? '0'; $spentPct = '0';
$spentPct = '0';
$budgeted = $entry['budgeted']; $budgeted = $entry['budgeted'];
$totalBudgeted = $report['sums'][$currencyId]['budgeted'] ?? '0';; $totalBudgeted = $report['sums'][$currencyId]['budgeted'] ?? '0';
$budgetedPct = '0'; $budgetedPct = '0';
if (0 !== bccomp($spent, '0') && 0 !== bccomp($totalSpent, '0')) { if (0 !== bccomp($spent, '0') && 0 !== bccomp($totalSpent, '0')) {
$spentPct = round(bcmul(bcdiv($spent, $totalSpent), '100')); $spentPct = round(bcmul(bcdiv($spent, $totalSpent), '100'));
@ -427,28 +426,13 @@ class BudgetController extends Controller
if (0 !== bccomp($budgeted, '0') && 0 !== bccomp($totalBudgeted, '0')) { if (0 !== bccomp($budgeted, '0') && 0 !== bccomp($totalBudgeted, '0')) {
$budgetedPct = round(bcmul(bcdiv($budgeted, $totalBudgeted), '100')); $budgetedPct = round(bcmul(bcdiv($budgeted, $totalBudgeted), '100'));
} }
$report['sums'][$currencyId]['budgeted'] = $report['sums'][$currencyId]['budgeted'] ?? '0';
$report['budgets'][$budgetId]['budget_limits'][$limitId]['spent_pct'] = $spentPct; $report['budgets'][$budgetId]['budget_limits'][$limitId]['spent_pct'] = $spentPct;
$report['budgets'][$budgetId]['budget_limits'][$limitId]['budgeted_pct'] = $budgetedPct; $report['budgets'][$budgetId]['budget_limits'][$limitId]['budgeted_pct'] = $budgetedPct;
} }
} }
// var_dump($noBudget); return view('reports.partials.budgets', compact('report'))->render();
//
//
// echo '<pre>';
// print_r($report);
// exit;
// try {
$result = view('reports.partials.budgets', compact('report'))->render();
// @codeCoverageIgnoreStart
// } catch (Throwable $e) {
// Log::debug(sprintf('Could not render reports.partials.budgets: %s', $e->getMessage()));
// $result = 'Could not render view.';
// }
// @codeCoverageIgnoreEnd
return $result;
} }
/** /**

View File

@ -714,7 +714,6 @@ class CategoryController extends Controller
/** @var NoCategoryRepositoryInterface $noCatRepository */ /** @var NoCategoryRepositoryInterface $noCatRepository */
$noCatRepository = app(NoCategoryRepositoryInterface::class); $noCatRepository = app(NoCategoryRepositoryInterface::class);
$categories = $repository->getCategories();
$earnedWith = $opsRepository->listIncome($start, $end, $accounts); $earnedWith = $opsRepository->listIncome($start, $end, $accounts);
$spentWith = $opsRepository->listExpenses($start, $end, $accounts); $spentWith = $opsRepository->listExpenses($start, $end, $accounts);
$earnedWithout = $noCatRepository->listIncome($start, $end, $accounts); $earnedWithout = $noCatRepository->listIncome($start, $end, $accounts);
@ -745,7 +744,7 @@ class CategoryController extends Controller
$key = sprintf('%s-%s', $currencyId, $categoryId); $key = sprintf('%s-%s', $currencyId, $categoryId);
$report['categories'][$key] = $report['categories'][$key] ?? [ $report['categories'][$key] = $report['categories'][$key] ?? [
'id' => $categoryId, 'id' => $categoryId,
'title' => sprintf('%s (%s)', $categoryRow['name'], $currencyRow['currency_name']), 'title' => $categoryRow['name'],
'currency_id' => $currencyRow['currency_id'], 'currency_id' => $currencyRow['currency_id'],
'currency_symbol' => $currencyRow['currency_symbol'], 'currency_symbol' => $currencyRow['currency_symbol'],
'currency_name' => $currencyRow['currency_name'], 'currency_name' => $currencyRow['currency_name'],

View File

@ -69,6 +69,8 @@ class EditController extends Controller
*/ */
public function edit(TransactionGroup $transactionGroup) public function edit(TransactionGroup $transactionGroup)
{ {
app('preferences')->mark();
if (!$this->isEditableGroup($transactionGroup)) { if (!$this->isEditableGroup($transactionGroup)) {
return $this->redirectGroupToAccount($transactionGroup); // @codeCoverageIgnore return $this->redirectGroupToAccount($transactionGroup); // @codeCoverageIgnore
} }

View File

@ -182,7 +182,7 @@ class Kernel extends HttpKernel
'apiX' => [ 'apiX' => [
'auth:api', 'auth:api',
'throttle:60,1', //'throttle:60,1',
'bindings', 'bindings',
], ],
]; ];

View File

@ -27,6 +27,7 @@ namespace FireflyIII\Http\Middleware;
use Closure; use Closure;
use DB; use DB;
use FireflyIII\Exceptions\FireflyException; use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Support\System\OAuthKeys;
use Illuminate\Database\QueryException; use Illuminate\Database\QueryException;
use Log; use Log;
@ -71,6 +72,7 @@ class Installer
if ($this->hasNoTables() || $this->oldDBVersion() || $this->oldVersion()) { if ($this->hasNoTables() || $this->oldDBVersion() || $this->oldVersion()) {
return response()->redirectTo(route('installer.index')); return response()->redirectTo(route('installer.index'));
} }
OAuthKeys::verifyKeysRoutine();
// update scheme version // update scheme version
// update firefly version // update firefly version
@ -182,4 +184,5 @@ class Installer
return false; return false;
} }
} }

View File

@ -53,8 +53,6 @@ class Range
// set more view variables: // set more view variables:
$this->configureList(); $this->configureList();
// flash a big fat warning when users use SQLite in Docker
$this->loseItAll($request);
} }
return $next($request); return $next($request);
@ -104,22 +102,6 @@ class Range
app('view')->share('defaultCurrency', $defaultCurrency); app('view')->share('defaultCurrency', $defaultCurrency);
} }
/**
* Error when sqlite in docker.
*
* @param Request $request
*/
private function loseItAll(Request $request): void
{
if ('sqlite' === config('database.default') && true === config('firefly.is_docker')) {
// @codeCoverageIgnoreStart
$request->session()->flash(
'error', 'You seem to be using SQLite in a Docker container. Don\'t do this. If the container restarts all your data will be gone.'
);
// @codeCoverageIgnoreEnd
}
}
/** /**
* Set the range for the current view. * Set the range for the current view.
*/ */

View File

@ -1,7 +1,7 @@
<?php <?php
/** /**
* FinTSConfigurationSteps.php * FinTSConfigurationSteps.php
* Copyright (c) 2019 thegrumpydictator@gmail.com * Copyright (c) 2019 https://github.com/bnw
* *
* This file is part of Firefly III (https://github.com/firefly-iii). * This file is part of Firefly III (https://github.com/firefly-iii).
* *

View File

@ -1,7 +1,7 @@
<?php <?php
/** /**
* FinTSJobConfiguration.php * FinTSJobConfiguration.php
* Copyright (c) 2019 thegrumpydictator@gmail.com * Copyright (c) 2019 https://github.com/bnw
* *
* This file is part of Firefly III (https://github.com/firefly-iii). * This file is part of Firefly III (https://github.com/firefly-iii).
* *

View File

@ -1,7 +1,7 @@
<?php <?php
/** /**
* FinTSRoutine.php * FinTSRoutine.php
* Copyright (c) 2019 thegrumpydictator@gmail.com * Copyright (c) 2019 https://github.com/bnw
* *
* This file is part of Firefly III (https://github.com/firefly-iii). * This file is part of Firefly III (https://github.com/firefly-iii).
* *

View File

@ -1,7 +1,7 @@
<?php <?php
/** /**
* AbnAmroDescription.php * AbnAmroDescription.php
* Copyright (c) 2019 thegrumpydictator@gmail.com * Copyright (c) 2019 Robert Horlings
* *
* This file is part of Firefly III (https://github.com/firefly-iii). * This file is part of Firefly III (https://github.com/firefly-iii).
* *

View File

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Belfius.php * Belfius.php
* Copyright (c) 2019 thegrumpydictator@gmail.com * Copyright (c) 2019 Sander Kleykens <sander@kleykens.com>
* *
* This file is part of Firefly III (https://github.com/firefly-iii). * This file is part of Firefly III (https://github.com/firefly-iii).
* *

View File

@ -1,7 +1,7 @@
<?php <?php
/** /**
* IngBelgium.php * IngBelgium.php
* Copyright (c) 2019 thegrumpydictator@gmail.com * Copyright (c) 2019 Sander Kleykens <sander@kleykens.com>
* *
* This file is part of Firefly III (https://github.com/firefly-iii). * This file is part of Firefly III (https://github.com/firefly-iii).
* *

View File

@ -1,7 +1,7 @@
<?php <?php
/** /**
* IngDescription.php * IngDescription.php
* Copyright (c) 2019 thegrumpydictator@gmail.com * Copyright (c) 2019 https://github.com/tomwerf
* *
* This file is part of Firefly III (https://github.com/firefly-iii). * This file is part of Firefly III (https://github.com/firefly-iii).
* *

View File

@ -1,7 +1,7 @@
<?php <?php
/** /**
* SnsDescription.php * SnsDescription.php
* Copyright (c) 2019 thegrumpydictator@gmail.com * Copyright (c) 2019 hugovanduijn@gmail.com.
* *
* This file is part of Firefly III (https://github.com/firefly-iii). * This file is part of Firefly III (https://github.com/firefly-iii).
* *

View File

@ -134,6 +134,10 @@ class CreateRecurringTransactions implements ShouldQueue
$this->repository->setUser($recurrence->user); $this->repository->setUser($recurrence->user);
$this->journalRepository->setUser($recurrence->user); $this->journalRepository->setUser($recurrence->user);
$this->groupRepository->setUser($recurrence->user); $this->groupRepository->setUser($recurrence->user);
// clear cache for user
app('preferences')->setForUser($recurrence->user, 'lastActivity', microtime());
Log::debug(sprintf('Now at recurrence #%d', $recurrence->id)); Log::debug(sprintf('Now at recurrence #%d', $recurrence->id));
$created = $this->handleRepetitions($recurrence); $created = $this->handleRepetitions($recurrence);
Log::debug(sprintf('Done with recurrence #%d', $recurrence->id)); Log::debug(sprintf('Done with recurrence #%d', $recurrence->id));

View File

@ -318,9 +318,8 @@ class AccountRepository implements AccountRepositoryInterface
$query->where('active', 1); $query->where('active', 1);
$query->orderBy('accounts.account_type_id', 'ASC'); $query->orderBy('accounts.account_type_id', 'ASC');
$query->orderBy('accounts.name', 'ASC'); $query->orderBy('accounts.name', 'ASC');
$result = $query->get(['accounts.*']);
return $result; return $query->get(['accounts.*']);
} }
/** /**
@ -606,4 +605,27 @@ class AccountRepository implements AccountRepositoryInterface
return $account; return $account;
} }
/**
* @param array $types
*
* @return Collection
*/
public function getInactiveAccountsByType(array $types): Collection
{
/** @var Collection $result */
$query = $this->user->accounts()->with(
['accountmeta' => function (HasMany $query) {
$query->where('name', 'account_role');
}]
);
if (count($types) > 0) {
$query->accountTypeIn($types);
}
$query->where('active', 0);
$query->orderBy('accounts.account_type_id', 'ASC');
$query->orderBy('accounts.name', 'ASC');
return $query->get(['accounts.*']);
}
} }

View File

@ -142,6 +142,13 @@ interface AccountRepositoryInterface
*/ */
public function getActiveAccountsByType(array $types): Collection; public function getActiveAccountsByType(array $types): Collection;
/**
* @param array $types
*
* @return Collection
*/
public function getInactiveAccountsByType(array $types): Collection;
/** /**
* @return Account * @return Account
*/ */

View File

@ -404,6 +404,7 @@ class RecurringRepository implements RecurringRepositoryInterface
*/ */
public function repetitionDescription(RecurrenceRepetition $repetition): string public function repetitionDescription(RecurrenceRepetition $repetition): string
{ {
Log::debug('Now in repetitionDescription()');
/** @var Preference $pref */ /** @var Preference $pref */
$pref = app('preferences')->getForUser($this->user, 'language', config('firefly.default_language', 'en_US')); $pref = app('preferences')->getForUser($this->user, 'language', config('firefly.default_language', 'en_US'));
$language = $pref->data; $language = $pref->data;
@ -514,6 +515,7 @@ class RecurringRepository implements RecurringRepositoryInterface
*/ */
public function getXOccurrencesSince(RecurrenceRepetition $repetition, Carbon $date, Carbon $afterDate, int $count): array public function getXOccurrencesSince(RecurrenceRepetition $repetition, Carbon $date, Carbon $afterDate, int $count): array
{ {
Log::debug('Now in getXOccurrencesSince()');
$skipMod = $repetition->repetition_skip + 1; $skipMod = $repetition->repetition_skip + 1;
$occurrences = []; $occurrences = [];
if ('daily' === $repetition->repetition_type) { if ('daily' === $repetition->repetition_type) {

View File

@ -97,6 +97,7 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface
$journals = $group->transactionJournals->pluck('id')->toArray(); $journals = $group->transactionJournals->pluck('id')->toArray();
$set = Attachment::whereIn('attachable_id', $journals) $set = Attachment::whereIn('attachable_id', $journals)
->where('attachable_type', TransactionJournal::class) ->where('attachable_type', TransactionJournal::class)
->where('uploaded', 1)
->whereNull('deleted_at')->get(); ->whereNull('deleted_at')->get();
$result = []; $result = [];

View File

@ -160,6 +160,10 @@ class BelongsUser implements Rule
*/ */
private function validateAccountId(int $value): bool private function validateAccountId(int $value): bool
{ {
if (0 === $value) {
// its ok to submit 0. other checks will fail.
return true;
}
$count = Account::where('id', '=', $value)->where('user_id', '=', auth()->user()->id)->count(); $count = Account::where('id', '=', $value)->where('user_id', '=', auth()->user()->id)->count();
return 1 === $count; return 1 === $count;

View File

@ -1,7 +1,7 @@
<?php <?php
/** /**
* RatesApiIOv1.php * RatesApiIOv1.php
* Copyright (c) 2019 thegrumpydictator@gmail.com * Copyright (c) 2019 https://github.com/BoGnY
* *
* This file is part of Firefly III (https://github.com/firefly-iii). * This file is part of Firefly III (https://github.com/firefly-iii).
* *

View File

@ -93,7 +93,16 @@ trait AccountServiceTrait
// if the field is set but NULL, skip it. // if the field is set but NULL, skip it.
// if the field is set but "", update it. // if the field is set but "", update it.
if (isset($data[$field]) && null !== $data[$field]) { if (isset($data[$field]) && null !== $data[$field]) {
$factory->crud($account, $field, (string)($data[$field] ?? ''));
// convert boolean value:
if (is_bool($data[$field]) && false === $data[$field]) {
$data[$field] = 0;
}
if (is_bool($data[$field]) && true === $data[$field]) {
$data[$field] = 1;
}
$factory->crud($account, $field, (string)$data[$field]);
} }
} }
} }

View File

@ -25,6 +25,7 @@ namespace FireflyIII\Services\Internal\Support;
use Exception; use Exception;
use FireflyIII\Exceptions\FireflyException; use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Factory\AccountMetaFactory;
use FireflyIII\Factory\TagFactory; use FireflyIII\Factory\TagFactory;
use FireflyIII\Models\Account; use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType; use FireflyIII\Models\AccountType;
@ -82,18 +83,17 @@ trait JournalServiceTrait
} }
/** /**
* @param string $transactionType * @param string $transactionType
* @param string $direction * @param string $direction
* @param int|null $accountId * @param array $data
* @param string|null $accountName
* *
* @return Account * @return Account
* @codeCoverageIgnore * @codeCoverageIgnore
*/ */
protected function getAccount(string $transactionType, string $direction, ?int $accountId, ?string $accountName): Account protected function getAccount(string $transactionType, string $direction, array $data): Account
{ {
// some debug logging: // some debug logging:
Log::debug(sprintf('Now in getAccount(%s, %d, %s)', $direction, $accountId, $accountName)); Log::debug(sprintf('Now in getAccount(%s)', $direction), $data);
// final result: // final result:
$result = null; $result = null;
@ -109,8 +109,8 @@ trait JournalServiceTrait
Log::debug(sprintf($message, $transactionType, $direction, implode(', ', $expectedTypes[$transactionType]))); Log::debug(sprintf($message, $transactionType, $direction, implode(', ', $expectedTypes[$transactionType])));
// first attempt, find by ID. // first attempt, find by ID.
if (null !== $accountId) { if (null !== $data['id']) {
$search = $this->accountRepository->findNull($accountId); $search = $this->accountRepository->findNull($data['id']);
if (null !== $search && in_array($search->accountType->type, $expectedTypes[$transactionType], true)) { if (null !== $search && in_array($search->accountType->type, $expectedTypes[$transactionType], true)) {
Log::debug( Log::debug(
sprintf('Found "account_id" object for %s: #%d, "%s" of type %s', $direction, $search->id, $search->name, $search->accountType->type) sprintf('Found "account_id" object for %s: #%d, "%s" of type %s', $direction, $search->id, $search->name, $search->accountType->type)
@ -120,12 +120,12 @@ trait JournalServiceTrait
} }
// second attempt, find by name. // second attempt, find by name.
if (null === $result && null !== $accountName) { if (null === $result && null !== $data['name']) {
Log::debug('Found nothing by account ID.'); Log::debug('Found nothing by account ID.');
// find by preferred type. // find by preferred type.
$source = $this->accountRepository->findByName($accountName, [$expectedTypes[$transactionType][0]]); $source = $this->accountRepository->findByName($data['name'], [$expectedTypes[$transactionType][0]]);
// or any expected type. // or any expected type.
$source = $source ?? $this->accountRepository->findByName($accountName, $expectedTypes[$transactionType]); $source = $source ?? $this->accountRepository->findByName($data['name'], $expectedTypes[$transactionType]);
if (null !== $source) { if (null !== $source) {
Log::debug(sprintf('Found "account_name" object for %s: #%d, %s', $direction, $source->id, $source->name)); Log::debug(sprintf('Found "account_name" object for %s: #%d, %s', $direction, $source->id, $source->name));
@ -134,30 +134,57 @@ trait JournalServiceTrait
} }
} }
// third attempt, find by IBAN
if (null === $result && null !== $data['iban']) {
Log::debug('Found nothing by account name.');
// find by preferred type.
$source = $this->accountRepository->findByIbanNull($data['iban'], [$expectedTypes[$transactionType][0]]);
// or any expected type.
$source = $source ?? $this->accountRepository->findByIbanNull($data['iban'], $expectedTypes[$transactionType]);
if (null !== $source) {
Log::debug(sprintf('Found "account_iban" object for %s: #%d, %s', $direction, $source->id, $source->name));
$result = $source;
}
}
// return cash account. // return cash account.
if (null === $result && null === $accountName if (null === $result && null === $data['name']
&& in_array(AccountType::CASH, $expectedTypes[$transactionType], true)) { && in_array(AccountType::CASH, $expectedTypes[$transactionType], true)) {
$result = $this->accountRepository->getCashAccount(); $result = $this->accountRepository->getCashAccount();
} }
// return new account. // return new account.
if (null === $result) { if (null === $result) {
$accountName = $accountName ?? '(no name)'; $data['name'] = $data['name'] ?? '(no name)';
// final attempt, create it. // final attempt, create it.
$preferredType = $expectedTypes[$transactionType][0]; $preferredType = $expectedTypes[$transactionType][0];
if (AccountType::ASSET === $preferredType) { if (AccountType::ASSET === $preferredType) {
throw new FireflyException(sprintf('TransactionFactory: Cannot create asset account with ID #%d or name "%s".', $accountId, $accountName)); throw new FireflyException('TransactionFactory: Cannot create asset account with these values', $data);
} }
$result = $this->accountRepository->store( $result = $this->accountRepository->store(
[ [
'account_type_id' => null, 'account_type_id' => null,
'account_type' => $preferredType, 'account_type' => $preferredType,
'name' => $accountName, 'name' => $data['name'],
'active' => true, 'active' => true,
'iban' => null, 'iban' => $data['iban'],
] ]
); );
// store BIC
if (null !== $data['bic']) {
/** @var AccountMetaFactory $metaFactory */
$metaFactory = app(AccountMetaFactory::class);
$metaFactory->create(['account_id' => $result->id, 'name' => 'BIC', 'data' => $data['bic']]);
}
// store account number
if (null !== $data['number']) {
/** @var AccountMetaFactory $metaFactory */
$metaFactory = app(AccountMetaFactory::class);
$metaFactory->create(['account_id' => $result->id, 'name' => 'account_number', 'data' => $data['bic']]);
}
} }
return $result; return $result;

View File

@ -294,14 +294,19 @@ class JournalUpdateService
return $this->getOriginalDestinationAccount(); return $this->getOriginalDestinationAccount();
} }
$destId = $this->data['destination_id'] ?? null; $destInfo = [
$destName = $this->data['destination_name'] ?? null; 'id' => (int)($this->data['destination_id'] ?? null),
'name' => $this->data['destination_name'] ?? null,
'iban' => $this->data['destination_iban'] ?? null,
'number' => $this->data['destination_number'] ?? null,
'bic' => $this->data['destination_bic'] ?? null,
];
// make new account validator. // make new account validator.
$expectedType = $this->getExpectedType(); $expectedType = $this->getExpectedType();
Log::debug(sprintf('Expected type (new or unchanged) is %s', $expectedType)); Log::debug(sprintf('Expected type (new or unchanged) is %s', $expectedType));
try { try {
$result = $this->getAccount($expectedType, 'destination', $destId, $destName); $result = $this->getAccount($expectedType, 'destination', $destInfo);
} catch (FireflyException $e) { } catch (FireflyException $e) {
Log::error(sprintf('getValidDestinationAccount() threw unexpected error: %s', $e->getMessage())); Log::error(sprintf('getValidDestinationAccount() threw unexpected error: %s', $e->getMessage()));
$result = $this->getOriginalDestinationAccount(); $result = $this->getOriginalDestinationAccount();
@ -318,16 +323,22 @@ class JournalUpdateService
private function getValidSourceAccount(): Account private function getValidSourceAccount(): Account
{ {
Log::debug('Now in getValidSourceAccount().'); Log::debug('Now in getValidSourceAccount().');
$sourceId = $this->data['source_id'] ?? null;
$sourceName = $this->data['source_name'] ?? null;
if (!$this->hasFields(['source_id', 'source_name'])) { if (!$this->hasFields(['source_id', 'source_name'])) {
return $this->getOriginalSourceAccount(); return $this->getOriginalSourceAccount();
} }
$sourceInfo = [
'id' => (int)($this->data['source_id'] ?? null),
'name' => $this->data['source_name'] ?? null,
'iban' => $this->data['source_iban'] ?? null,
'number' => $this->data['source_number'] ?? null,
'bic' => $this->data['source_bic'] ?? null,
];
$expectedType = $this->getExpectedType(); $expectedType = $this->getExpectedType();
try { try {
$result = $this->getAccount($expectedType, 'source', $sourceId, $sourceName); $result = $this->getAccount($expectedType, 'source', $sourceInfo);
} catch (FireflyException $e) { } catch (FireflyException $e) {
Log::error(sprintf('Cant get the valid source account: %s', $e->getMessage())); Log::error(sprintf('Cant get the valid source account: %s', $e->getMessage()));

View File

@ -1,7 +1,7 @@
<?php <?php
/** /**
* FinTS.php * FinTS.php
* Copyright (c) 2019 thegrumpydictator@gmail.com * Copyright (c) 2019 https://github.com/bnw
* *
* This file is part of Firefly III (https://github.com/firefly-iii). * This file is part of Firefly III (https://github.com/firefly-iii).
* *

View File

@ -1,7 +1,7 @@
<?php <?php
/** /**
* MetadataParser.php * MetadataParser.php
* Copyright (c) 2019 thegrumpydictator@gmail.com * Copyright (c) 2019 https://github.com/bnw
* *
* This file is part of Firefly III (https://github.com/firefly-iii). * This file is part of Firefly III (https://github.com/firefly-iii).
* *

View File

@ -1,7 +1,7 @@
<?php <?php
/** /**
* ChooseAccountHandler.php * ChooseAccountHandler.php
* Copyright (c) 2019 thegrumpydictator@gmail.com * Copyright (c) 2019 https://github.com/bnw
* *
* This file is part of Firefly III (https://github.com/firefly-iii). * This file is part of Firefly III (https://github.com/firefly-iii).
* *

View File

@ -1,7 +1,7 @@
<?php <?php
/** /**
* FinTSConfigurationInterface.php * FinTSConfigurationInterface.php
* Copyright (c) 2019 thegrumpydictator@gmail.com * Copyright (c) 2019 https://github.com/bnw
* *
* This file is part of Firefly III (https://github.com/firefly-iii). * This file is part of Firefly III (https://github.com/firefly-iii).
* *

View File

@ -1,7 +1,7 @@
<?php <?php
/** /**
* NewFinTSJobHandler.php * NewFinTSJobHandler.php
* Copyright (c) 2019 thegrumpydictator@gmail.com * Copyright (c) 2019 https://github.com/bnw
* *
* This file is part of Firefly III (https://github.com/firefly-iii). * This file is part of Firefly III (https://github.com/firefly-iii).
* *

View File

@ -1,7 +1,7 @@
<?php <?php
/** /**
* StageImportDataHandler.php * StageImportDataHandler.php
* Copyright (c) 2019 thegrumpydictator@gmail.com * Copyright (c) 2019 https://github.com/bnw
* *
* This file is part of Firefly III (https://github.com/firefly-iii). * This file is part of Firefly III (https://github.com/firefly-iii).
* *

View File

@ -26,7 +26,7 @@ namespace FireflyIII\Support\Repositories\Recurring;
use Carbon\Carbon; use Carbon\Carbon;
use Log;
/** /**
* Class CalculateXOccurrencesSince * Class CalculateXOccurrencesSince
*/ */
@ -46,6 +46,7 @@ trait CalculateXOccurrencesSince
*/ */
protected function getXDailyOccurrencesSince(Carbon $date, Carbon $afterDate, int $count, int $skipMod): array protected function getXDailyOccurrencesSince(Carbon $date, Carbon $afterDate, int $count, int $skipMod): array
{ {
Log::debug(sprintf('Now in %s', __METHOD__));
$return = []; $return = [];
$mutator = clone $date; $mutator = clone $date;
$total = 0; $total = 0;
@ -77,6 +78,7 @@ trait CalculateXOccurrencesSince
*/ */
protected function getXMonthlyOccurrencesSince(Carbon $date, Carbon $afterDate, int $count, int $skipMod, string $moment): array protected function getXMonthlyOccurrencesSince(Carbon $date, Carbon $afterDate, int $count, int $skipMod, string $moment): array
{ {
Log::debug(sprintf('Now in %s', __METHOD__));
$return = []; $return = [];
$mutator = clone $date; $mutator = clone $date;
$total = 0; $total = 0;
@ -116,6 +118,7 @@ trait CalculateXOccurrencesSince
*/ */
protected function getXNDomOccurrencesSince(Carbon $date, Carbon $afterDate, int $count, int $skipMod, string $moment): array protected function getXNDomOccurrencesSince(Carbon $date, Carbon $afterDate, int $count, int $skipMod, string $moment): array
{ {
Log::debug(sprintf('Now in %s', __METHOD__));
$return = []; $return = [];
$total = 0; $total = 0;
$attempts = 0; $attempts = 0;
@ -156,6 +159,7 @@ trait CalculateXOccurrencesSince
*/ */
protected function getXWeeklyOccurrencesSince(Carbon $date, Carbon $afterDate, int $count, int $skipMod, string $moment): array protected function getXWeeklyOccurrencesSince(Carbon $date, Carbon $afterDate, int $count, int $skipMod, string $moment): array
{ {
Log::debug(sprintf('Now in %s', __METHOD__));
$return = []; $return = [];
$total = 0; $total = 0;
$attempts = 0; $attempts = 0;
@ -200,6 +204,7 @@ trait CalculateXOccurrencesSince
*/ */
protected function getXYearlyOccurrencesSince(Carbon $date, Carbon $afterDate, int $count, int $skipMod, string $moment): array protected function getXYearlyOccurrencesSince(Carbon $date, Carbon $afterDate, int $count, int $skipMod, string $moment): array
{ {
Log::debug(sprintf('Now in %s', __METHOD__));
$return = []; $return = [];
$mutator = clone $date; $mutator = clone $date;
$total = 0; $total = 0;

View File

@ -46,6 +46,7 @@ trait FiltersWeekends
*/ */
protected function filterWeekends(RecurrenceRepetition $repetition, array $dates): array protected function filterWeekends(RecurrenceRepetition $repetition, array $dates): array
{ {
Log::debug(sprintf('Now in %s', __METHOD__));
if ((int)$repetition->weekend === RecurrenceRepetition::WEEKEND_DO_NOTHING) { if ((int)$repetition->weekend === RecurrenceRepetition::WEEKEND_DO_NOTHING) {
Log::debug('Repetition will not be filtered on weekend days.'); Log::debug('Repetition will not be filtered on weekend days.');

View File

@ -108,7 +108,7 @@ class AccountSearch implements GenericSearchInterface
break; break;
} }
return $query->get(['accounts.*']); return $query->distinct()->get(['accounts.*']);
} }
/** /**

View File

@ -123,10 +123,13 @@ class Search implements SearchInterface
{ {
$filteredQuery = app('steam')->cleanString($query); $filteredQuery = app('steam')->cleanString($query);
$this->originalQuery = $filteredQuery; $this->originalQuery = $filteredQuery;
$pattern = '/[[:alpha:]_]*:"?[\p{L}_-]*"?/ui'; $pattern = '/[[:alpha:]_]*:"?[\P{C}_-]*"?/ui';
$matches = []; $matches = [];
preg_match_all($pattern, $filteredQuery, $matches); preg_match_all($pattern, $filteredQuery, $matches);
var_dump($matches[0]);
exit;
foreach ($matches[0] as $match) { foreach ($matches[0] as $match) {
$this->extractModifier($match); $this->extractModifier($match);
$filteredQuery = str_replace($match, '', $filteredQuery); $filteredQuery = str_replace($match, '', $filteredQuery);
@ -288,12 +291,12 @@ class Search implements SearchInterface
$after = new Carbon($modifier['value']); $after = new Carbon($modifier['value']);
$collector->setAfter($after); $collector->setAfter($after);
break; break;
case 'created_at': case 'created_on':
Log::debug(sprintf('Set "%s" using collector with value "%s"', $modifier['type'], $modifier['value'])); Log::debug(sprintf('Set "%s" using collector with value "%s"', $modifier['type'], $modifier['value']));
$createdAt = new Carbon($modifier['value']); $createdAt = new Carbon($modifier['value']);
$collector->setCreatedAt($createdAt); $collector->setCreatedAt($createdAt);
break; break;
case 'updated_at': case 'updated_on':
Log::debug(sprintf('Set "%s" using collector with value "%s"', $modifier['type'], $modifier['value'])); Log::debug(sprintf('Set "%s" using collector with value "%s"', $modifier['type'], $modifier['value']));
$updatedAt = new Carbon($modifier['value']); $updatedAt = new Carbon($modifier['value']);
$collector->setUpdatedAt($updatedAt); $collector->setUpdatedAt($updatedAt);

View File

@ -0,0 +1,111 @@
<?php
/**
* OAuthKeys.php
* Copyright (c) 2019 thegrumpydictator@gmail.com
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace FireflyIII\Support\System;
use Artisan;
use Crypt;
use Laravel\Passport\Console\KeysCommand;
/**
* Class OAuthKeys
*/
class OAuthKeys
{
private const PRIVATE_KEY = 'oauth_private_key';
private const PUBLIC_KEY = 'oauth_public_key';
/**
*
*/
public static function generateKeys(): void
{
Artisan::registerCommand(new KeysCommand());
Artisan::call('passport:keys');
}
/**
* @return bool
*/
public static function hasKeyFiles(): bool
{
$private = storage_path('oauth-private.key');
$public = storage_path('oauth-public.key');
return file_exists($private) && file_exists($public);
}
/**
* @return bool
*/
public static function keysInDatabase(): bool
{
return app('fireflyconfig')->has(self::PRIVATE_KEY) && app('fireflyconfig')->has(self::PUBLIC_KEY);
}
/**
*
*/
public static function restoreKeysFromDB(): void
{
$privateContent = Crypt::decrypt(app('fireflyconfig')->get(self::PRIVATE_KEY)->data);
$publicContent = Crypt::decrypt(app('fireflyconfig')->get(self::PUBLIC_KEY)->data);
$private = storage_path('oauth-private.key');
$public = storage_path('oauth-public.key');
file_put_contents($private, $privateContent);
file_put_contents($public, $publicContent);
}
/**
*
*/
public static function storeKeysInDB(): void
{
$private = storage_path('oauth-private.key');
$public = storage_path('oauth-public.key');
app('fireflyconfig')->set(self::PRIVATE_KEY, Crypt::encrypt(file_get_contents($private)));
app('fireflyconfig')->set(self::PUBLIC_KEY, Crypt::encrypt(file_get_contents($public)));
}
/**
*
*/
public static function verifyKeysRoutine(): void
{
if (!self::keysInDatabase() && !self::hasKeyFiles()) {
self::generateKeys();
self::storeKeysInDB();
return;
}
if (self::keysInDatabase() && !self::hasKeyFiles()) {
self::restoreKeysFromDB();
return;
}
if (!self::keysInDatabase() && self::hasKeyFiles()) {
self::storeKeysInDB();
return;
}
}
}

View File

@ -229,7 +229,7 @@ class RuleEngine
$validTrigger = ('store-journal' === $trigger->trigger_value && self::TRIGGER_STORE === $this->triggerMode) $validTrigger = ('store-journal' === $trigger->trigger_value && self::TRIGGER_STORE === $this->triggerMode)
|| ('update-journal' === $trigger->trigger_value && self::TRIGGER_UPDATE === $this->triggerMode); || ('update-journal' === $trigger->trigger_value && self::TRIGGER_UPDATE === $this->triggerMode);
return $validTrigger && ($this->allRules || in_array($rule->id, $this->rulesToApply, true)); return $validTrigger && ($this->allRules || in_array($rule->id, $this->rulesToApply, true)) && true === $rule->active;
} }
} }

View File

@ -1,7 +1,7 @@
<?php <?php
/** /**
* ActionFactory.php * ActionFactory.php
* Copyright (c) 2019 thegrumpydictator@gmail.com * Copyright (c) 2019 Robert Horlings
* *
* This file is part of Firefly III (https://github.com/firefly-iii). * This file is part of Firefly III (https://github.com/firefly-iii).
* *

View File

@ -1,7 +1,7 @@
<?php <?php
/** /**
* TriggerFactory.php * TriggerFactory.php
* Copyright (c) 2019 thegrumpydictator@gmail.com * Copyright (c) 2019 Robert Horlings
* *
* This file is part of Firefly III (https://github.com/firefly-iii). * This file is part of Firefly III (https://github.com/firefly-iii).
* *

View File

@ -83,10 +83,12 @@ class RecurrenceTransformer extends AbstractTransformer
$this->piggyRepos->setUser($recurrence->user); $this->piggyRepos->setUser($recurrence->user);
$this->factory->setUser($recurrence->user); $this->factory->setUser($recurrence->user);
$this->budgetRepos->setUser($recurrence->user); $this->budgetRepos->setUser($recurrence->user);
Log::debug('Set user.');
$shortType = (string)config(sprintf('firefly.transactionTypesToShort.%s', $recurrence->transactionType->type)); $shortType = (string)config(sprintf('firefly.transactionTypesToShort.%s', $recurrence->transactionType->type));
$notes = $this->repository->getNoteText($recurrence); $notes = $this->repository->getNoteText($recurrence);
$reps = 0 === (int)$recurrence->repetitions ? null : (int)$recurrence->repetitions; $reps = 0 === (int)$recurrence->repetitions ? null : (int)$recurrence->repetitions;
Log::debug('Get basic data.');
// basic data. // basic data.
$return = [ $return = [
'id' => (int)$recurrence->id, 'id' => (int)$recurrence->id,
@ -124,6 +126,7 @@ class RecurrenceTransformer extends AbstractTransformer
*/ */
private function getRepetitions(Recurrence $recurrence): array private function getRepetitions(Recurrence $recurrence): array
{ {
Log::debug('Now in getRepetitions().');
$fromDate = $recurrence->latest_date ?? $recurrence->first_date; $fromDate = $recurrence->latest_date ?? $recurrence->first_date;
$return = []; $return = [];
@ -163,6 +166,7 @@ class RecurrenceTransformer extends AbstractTransformer
*/ */
private function getTransactionMeta(RecurrenceTransaction $transaction, array $array): array private function getTransactionMeta(RecurrenceTransaction $transaction, array $array): array
{ {
Log::debug(sprintf('Now in %s', __METHOD__));
$array['tags'] = []; $array['tags'] = [];
$array['category_id'] = null; $array['category_id'] = null;
$array['category_name'] = null; $array['category_name'] = null;
@ -216,6 +220,7 @@ class RecurrenceTransformer extends AbstractTransformer
*/ */
private function getTransactions(Recurrence $recurrence): array private function getTransactions(Recurrence $recurrence): array
{ {
Log::debug(sprintf('Now in %s', __METHOD__));
$return = []; $return = [];
// get all transactions: // get all transactions:
/** @var RecurrenceTransaction $transaction */ /** @var RecurrenceTransaction $transaction */

View File

@ -2,6 +2,44 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/). This project adheres to [Semantic Versioning](http://semver.org/).
## [4.8.1.5 (API 0.10.4)] - 2019-10-21
### Added
- [Issue 2694](https://github.com/firefly-iii/firefly-iii/issues/2694) Special page for archived accounts.
### Changed
- [Issue 2540](https://github.com/firefly-iii/firefly-iii/issues/2540) Partly translated transaction edit/create form.
- [Issue 2655](https://github.com/firefly-iii/firefly-iii/issues/2655) Link to Firefly III's base Docker image.
- [Issue 2724](https://github.com/firefly-iii/firefly-iii/issues/2724) Cleanup some JS output.
- [Issue 2734](https://github.com/firefly-iii/firefly-iii/issues/2734) Put personal access token in textarea for easier copy/pasting.
- [Issue 2728](https://github.com/firefly-iii/firefly-iii/issues/2728) Remove superfluous currency names.
### Deprecated
- Initial release.
### Removed
- Initial release.
### Fixed
- [Issue 2699](https://github.com/firefly-iii/firefly-iii/issues/2699) Internal cache wouldn't update.
- [Issue 2713](https://github.com/firefly-iii/firefly-iii/issues/2713) Could not search for numerical values.
- [Issue 2716](https://github.com/firefly-iii/firefly-iii/issues/2716) Could not reset intro popups.
- [Issue 2701](https://github.com/firefly-iii/firefly-iii/issues/2701) Temporary fix for timeouts.
- [Issue 2727](https://github.com/firefly-iii/firefly-iii/issues/2727) CSP headers too strict.
- [Issue 2731](https://github.com/firefly-iii/firefly-iii/issues/2731) Too strict config vars.
- [Issue 2754](https://github.com/firefly-iii/firefly-iii/issues/2754) Memcached config would error out.
- [Issue 2746](https://github.com/firefly-iii/firefly-iii/issues/2746) Cache would not clear after firing recurring transactions.
- [Issue 2755](https://github.com/firefly-iii/firefly-iii/issues/2755) Making a rule inactive would still fire it.
### Security
- Initial release.
### API
- [Issue 2698](https://github.com/firefly-iii/firefly-iii/issues/2698) Fix return value in API.
- [Issue 2753](https://github.com/firefly-iii/firefly-iii/issues/2753) Was possible to upload and manage empty attachments.
- New accounts submitted through the API may include account number, BIC and IBAN data.
- New end point to support [issue 2752](https://github.com/firefly-iii/firefly-iii/issues/2752).
## [4.8.1.4 (API 0.10.3)] - 2019-10-05 ## [4.8.1.4 (API 0.10.3)] - 2019-10-05
Emergency fix because I borked the upgrade routine. I apologise for the inconvenience. Emergency fix because I borked the upgrade routine. I apologise for the inconvenience.

View File

@ -84,6 +84,7 @@
"league/fractal": "0.*", "league/fractal": "0.*",
"litipk/flysystem-fallback-adapter": "0.*", "litipk/flysystem-fallback-adapter": "0.*",
"mschindler83/fints-hbci-php": "1.*", "mschindler83/fints-hbci-php": "1.*",
"pragmarx/google2fa": "7.*",
"pragmarx/google2fa-laravel": "1.*", "pragmarx/google2fa-laravel": "1.*",
"pragmarx/recovery": "^0.1.0", "pragmarx/recovery": "^0.1.0",
"rcrowe/twigbridge": "0.9.*" "rcrowe/twigbridge": "0.9.*"

294
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "3f739750fe2fcd798a369d0547753daa", "content-hash": "2bb65bbd943e05cc3619e7ddc4add0b6",
"packages": [ "packages": [
{ {
"name": "adldap2/adldap2", "name": "adldap2/adldap2",
@ -403,16 +403,16 @@
}, },
{ {
"name": "davejamesmiller/laravel-breadcrumbs", "name": "davejamesmiller/laravel-breadcrumbs",
"version": "5.3.0", "version": "5.3.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/davejamesmiller/laravel-breadcrumbs.git", "url": "https://github.com/davejamesmiller/laravel-breadcrumbs.git",
"reference": "1edeee4a77f467293aa5e5ea4a0b8f010216b8da" "reference": "40a73bc9b32fbbee18938dc92228dea161365245"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/davejamesmiller/laravel-breadcrumbs/zipball/1edeee4a77f467293aa5e5ea4a0b8f010216b8da", "url": "https://api.github.com/repos/davejamesmiller/laravel-breadcrumbs/zipball/40a73bc9b32fbbee18938dc92228dea161365245",
"reference": "1edeee4a77f467293aa5e5ea4a0b8f010216b8da", "reference": "40a73bc9b32fbbee18938dc92228dea161365245",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -458,7 +458,7 @@
"keywords": [ "keywords": [
"laravel" "laravel"
], ],
"time": "2019-09-03T15:24:57+00:00" "time": "2019-10-20T18:25:39+00:00"
}, },
{ {
"name": "defuse/php-encryption", "name": "defuse/php-encryption",
@ -1522,16 +1522,16 @@
}, },
{ {
"name": "laravel/passport", "name": "laravel/passport",
"version": "v7.5.0", "version": "v7.5.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/laravel/passport.git", "url": "https://github.com/laravel/passport.git",
"reference": "663e720a6d15e8ec70bf5309f774439a110efc89" "reference": "d63cdd672c3d65b3c35b73d0ef13a9dbfcb71c08"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/laravel/passport/zipball/663e720a6d15e8ec70bf5309f774439a110efc89", "url": "https://api.github.com/repos/laravel/passport/zipball/d63cdd672c3d65b3c35b73d0ef13a9dbfcb71c08",
"reference": "663e720a6d15e8ec70bf5309f774439a110efc89", "reference": "d63cdd672c3d65b3c35b73d0ef13a9dbfcb71c08",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1589,7 +1589,7 @@
"oauth", "oauth",
"passport" "passport"
], ],
"time": "2019-09-24T20:59:35+00:00" "time": "2019-10-08T16:45:24+00:00"
}, },
{ {
"name": "laravelcollective/html", "name": "laravelcollective/html",
@ -1786,16 +1786,16 @@
}, },
{ {
"name": "league/csv", "name": "league/csv",
"version": "9.4.0", "version": "9.4.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/thephpleague/csv.git", "url": "https://github.com/thephpleague/csv.git",
"reference": "e7225b6cc853942caef1c9c4d8889b716c34bc04" "reference": "bf83acc23a7d60978fce36a384f97bf9d7d2ea0c"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/thephpleague/csv/zipball/e7225b6cc853942caef1c9c4d8889b716c34bc04", "url": "https://api.github.com/repos/thephpleague/csv/zipball/bf83acc23a7d60978fce36a384f97bf9d7d2ea0c",
"reference": "e7225b6cc853942caef1c9c4d8889b716c34bc04", "reference": "bf83acc23a7d60978fce36a384f97bf9d7d2ea0c",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1851,7 +1851,7 @@
"read", "read",
"write" "write"
], ],
"time": "2019-10-02T18:32:54+00:00" "time": "2019-10-17T06:05:32+00:00"
}, },
{ {
"name": "league/event", "name": "league/event",
@ -1905,16 +1905,16 @@
}, },
{ {
"name": "league/flysystem", "name": "league/flysystem",
"version": "1.0.55", "version": "1.0.57",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/thephpleague/flysystem.git", "url": "https://github.com/thephpleague/flysystem.git",
"reference": "33c91155537c6dc899eacdc54a13ac6303f156e6" "reference": "0e9db7f0b96b9f12dcf6f65bc34b72b1a30ea55a"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/thephpleague/flysystem/zipball/33c91155537c6dc899eacdc54a13ac6303f156e6", "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/0e9db7f0b96b9f12dcf6f65bc34b72b1a30ea55a",
"reference": "33c91155537c6dc899eacdc54a13ac6303f156e6", "reference": "0e9db7f0b96b9f12dcf6f65bc34b72b1a30ea55a",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1985,7 +1985,7 @@
"sftp", "sftp",
"storage" "storage"
], ],
"time": "2019-08-24T11:17:19+00:00" "time": "2019-10-16T21:01:05+00:00"
}, },
{ {
"name": "league/flysystem-replicate-adapter", "name": "league/flysystem-replicate-adapter",
@ -2035,16 +2035,16 @@
}, },
{ {
"name": "league/flysystem-sftp", "name": "league/flysystem-sftp",
"version": "1.0.21", "version": "1.0.22",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/thephpleague/flysystem-sftp.git", "url": "https://github.com/thephpleague/flysystem-sftp.git",
"reference": "4c2f2fcc4da251127c315d37eb3dfa5e94658df0" "reference": "cab59dd2277e02fe46f5f23195672a02ed49774d"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/thephpleague/flysystem-sftp/zipball/4c2f2fcc4da251127c315d37eb3dfa5e94658df0", "url": "https://api.github.com/repos/thephpleague/flysystem-sftp/zipball/cab59dd2277e02fe46f5f23195672a02ed49774d",
"reference": "4c2f2fcc4da251127c315d37eb3dfa5e94658df0", "reference": "cab59dd2277e02fe46f5f23195672a02ed49774d",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -2073,7 +2073,7 @@
} }
], ],
"description": "Flysystem adapter for SFTP", "description": "Flysystem adapter for SFTP",
"time": "2019-09-19T09:11:05+00:00" "time": "2019-10-16T20:05:49+00:00"
}, },
{ {
"name": "league/fractal", "name": "league/fractal",
@ -2372,16 +2372,16 @@
}, },
{ {
"name": "nesbot/carbon", "name": "nesbot/carbon",
"version": "2.25.0", "version": "2.25.3",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/briannesbitt/Carbon.git", "url": "https://github.com/briannesbitt/Carbon.git",
"reference": "b70da677101cca7b584c7489770d2677c2733593" "reference": "d07636581795383e2fea2d711212d30f941f2039"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/b70da677101cca7b584c7489770d2677c2733593", "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/d07636581795383e2fea2d711212d30f941f2039",
"reference": "b70da677101cca7b584c7489770d2677c2733593", "reference": "d07636581795383e2fea2d711212d30f941f2039",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -2435,20 +2435,20 @@
"datetime", "datetime",
"time" "time"
], ],
"time": "2019-09-30T16:22:22+00:00" "time": "2019-10-20T11:05:44+00:00"
}, },
{ {
"name": "opis/closure", "name": "opis/closure",
"version": "3.4.0", "version": "3.4.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/opis/closure.git", "url": "https://github.com/opis/closure.git",
"reference": "60a97fff133b1669a5b1776aa8ab06db3f3962b7" "reference": "e79f851749c3caa836d7ccc01ede5828feb762c7"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/opis/closure/zipball/60a97fff133b1669a5b1776aa8ab06db3f3962b7", "url": "https://api.github.com/repos/opis/closure/zipball/e79f851749c3caa836d7ccc01ede5828feb762c7",
"reference": "60a97fff133b1669a5b1776aa8ab06db3f3962b7", "reference": "e79f851749c3caa836d7ccc01ede5828feb762c7",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -2496,7 +2496,7 @@
"serialization", "serialization",
"serialize" "serialize"
], ],
"time": "2019-09-02T21:07:33+00:00" "time": "2019-10-19T18:38:51+00:00"
}, },
{ {
"name": "paragonie/constant_time_encoding", "name": "paragonie/constant_time_encoding",
@ -2749,16 +2749,16 @@
}, },
{ {
"name": "pragmarx/google2fa", "name": "pragmarx/google2fa",
"version": "v6.1.0", "version": "v7.0.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/antonioribeiro/google2fa.git", "url": "https://github.com/antonioribeiro/google2fa.git",
"reference": "0ea122e0d1ba197e867888a623059ae1a7fe43b6" "reference": "0afb47f8a686bd203fe85a05bab85139f3c1971e"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/antonioribeiro/google2fa/zipball/0ea122e0d1ba197e867888a623059ae1a7fe43b6", "url": "https://api.github.com/repos/antonioribeiro/google2fa/zipball/0afb47f8a686bd203fe85a05bab85139f3c1971e",
"reference": "0ea122e0d1ba197e867888a623059ae1a7fe43b6", "reference": "0afb47f8a686bd203fe85a05bab85139f3c1971e",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -2801,7 +2801,7 @@
"Two Factor Authentication", "Two Factor Authentication",
"google2fa" "google2fa"
], ],
"time": "2019-09-23T18:30:35+00:00" "time": "2019-10-21T17:49:22+00:00"
}, },
{ {
"name": "pragmarx/google2fa-laravel", "name": "pragmarx/google2fa-laravel",
@ -3563,16 +3563,16 @@
}, },
{ {
"name": "symfony/console", "name": "symfony/console",
"version": "v4.3.4", "version": "v4.3.5",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/console.git", "url": "https://github.com/symfony/console.git",
"reference": "de63799239b3881b8a08f8481b22348f77ed7b36" "reference": "929ddf360d401b958f611d44e726094ab46a7369"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/de63799239b3881b8a08f8481b22348f77ed7b36", "url": "https://api.github.com/repos/symfony/console/zipball/929ddf360d401b958f611d44e726094ab46a7369",
"reference": "de63799239b3881b8a08f8481b22348f77ed7b36", "reference": "929ddf360d401b958f611d44e726094ab46a7369",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -3634,20 +3634,20 @@
], ],
"description": "Symfony Console Component", "description": "Symfony Console Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2019-08-26T08:26:39+00:00" "time": "2019-10-07T12:36:49+00:00"
}, },
{ {
"name": "symfony/css-selector", "name": "symfony/css-selector",
"version": "v4.3.4", "version": "v4.3.5",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/css-selector.git", "url": "https://github.com/symfony/css-selector.git",
"reference": "c6e5e2a00db768c92c3ae131532af4e1acc7bd03" "reference": "f4b3ff6a549d9ed28b2b0ecd1781bf67cf220ee9"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/css-selector/zipball/c6e5e2a00db768c92c3ae131532af4e1acc7bd03", "url": "https://api.github.com/repos/symfony/css-selector/zipball/f4b3ff6a549d9ed28b2b0ecd1781bf67cf220ee9",
"reference": "c6e5e2a00db768c92c3ae131532af4e1acc7bd03", "reference": "f4b3ff6a549d9ed28b2b0ecd1781bf67cf220ee9",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -3687,20 +3687,20 @@
], ],
"description": "Symfony CssSelector Component", "description": "Symfony CssSelector Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2019-08-20T14:07:54+00:00" "time": "2019-10-02T08:36:26+00:00"
}, },
{ {
"name": "symfony/debug", "name": "symfony/debug",
"version": "v4.3.4", "version": "v4.3.5",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/debug.git", "url": "https://github.com/symfony/debug.git",
"reference": "afcdea44a2e399c1e4b52246ec8d54c715393ced" "reference": "cc5c1efd0edfcfd10b354750594a46b3dd2afbbe"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/debug/zipball/afcdea44a2e399c1e4b52246ec8d54c715393ced", "url": "https://api.github.com/repos/symfony/debug/zipball/cc5c1efd0edfcfd10b354750594a46b3dd2afbbe",
"reference": "afcdea44a2e399c1e4b52246ec8d54c715393ced", "reference": "cc5c1efd0edfcfd10b354750594a46b3dd2afbbe",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -3743,20 +3743,20 @@
], ],
"description": "Symfony Debug Component", "description": "Symfony Debug Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2019-08-20T14:27:59+00:00" "time": "2019-09-19T15:51:53+00:00"
}, },
{ {
"name": "symfony/event-dispatcher", "name": "symfony/event-dispatcher",
"version": "v4.3.4", "version": "v4.3.5",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/event-dispatcher.git", "url": "https://github.com/symfony/event-dispatcher.git",
"reference": "429d0a1451d4c9c4abe1959b2986b88794b9b7d2" "reference": "6229f58993e5a157f6096fc7145c0717d0be8807"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/429d0a1451d4c9c4abe1959b2986b88794b9b7d2", "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/6229f58993e5a157f6096fc7145c0717d0be8807",
"reference": "429d0a1451d4c9c4abe1959b2986b88794b9b7d2", "reference": "6229f58993e5a157f6096fc7145c0717d0be8807",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -3813,20 +3813,20 @@
], ],
"description": "Symfony EventDispatcher Component", "description": "Symfony EventDispatcher Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2019-08-26T08:55:16+00:00" "time": "2019-10-01T16:40:32+00:00"
}, },
{ {
"name": "symfony/event-dispatcher-contracts", "name": "symfony/event-dispatcher-contracts",
"version": "v1.1.5", "version": "v1.1.7",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/event-dispatcher-contracts.git", "url": "https://github.com/symfony/event-dispatcher-contracts.git",
"reference": "c61766f4440ca687de1084a5c00b08e167a2575c" "reference": "c43ab685673fb6c8d84220c77897b1d6cdbe1d18"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/c61766f4440ca687de1084a5c00b08e167a2575c", "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/c43ab685673fb6c8d84220c77897b1d6cdbe1d18",
"reference": "c61766f4440ca687de1084a5c00b08e167a2575c", "reference": "c43ab685673fb6c8d84220c77897b1d6cdbe1d18",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -3871,20 +3871,20 @@
"interoperability", "interoperability",
"standards" "standards"
], ],
"time": "2019-06-20T06:46:26+00:00" "time": "2019-09-17T09:54:03+00:00"
}, },
{ {
"name": "symfony/finder", "name": "symfony/finder",
"version": "v4.3.4", "version": "v4.3.5",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/finder.git", "url": "https://github.com/symfony/finder.git",
"reference": "86c1c929f0a4b24812e1eb109262fc3372c8e9f2" "reference": "5e575faa95548d0586f6bedaeabec259714e44d1"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/finder/zipball/86c1c929f0a4b24812e1eb109262fc3372c8e9f2", "url": "https://api.github.com/repos/symfony/finder/zipball/5e575faa95548d0586f6bedaeabec259714e44d1",
"reference": "86c1c929f0a4b24812e1eb109262fc3372c8e9f2", "reference": "5e575faa95548d0586f6bedaeabec259714e44d1",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -3920,20 +3920,20 @@
], ],
"description": "Symfony Finder Component", "description": "Symfony Finder Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2019-08-14T12:26:46+00:00" "time": "2019-09-16T11:29:48+00:00"
}, },
{ {
"name": "symfony/http-foundation", "name": "symfony/http-foundation",
"version": "v4.3.4", "version": "v4.3.5",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/http-foundation.git", "url": "https://github.com/symfony/http-foundation.git",
"reference": "d804bea118ff340a12e22a79f9c7e7eb56b35adc" "reference": "76590ced16d4674780863471bae10452b79210a5"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/d804bea118ff340a12e22a79f9c7e7eb56b35adc", "url": "https://api.github.com/repos/symfony/http-foundation/zipball/76590ced16d4674780863471bae10452b79210a5",
"reference": "d804bea118ff340a12e22a79f9c7e7eb56b35adc", "reference": "76590ced16d4674780863471bae10452b79210a5",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -3975,20 +3975,20 @@
], ],
"description": "Symfony HttpFoundation Component", "description": "Symfony HttpFoundation Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2019-08-26T08:55:16+00:00" "time": "2019-10-04T19:48:13+00:00"
}, },
{ {
"name": "symfony/http-kernel", "name": "symfony/http-kernel",
"version": "v4.3.4", "version": "v4.3.5",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/http-kernel.git", "url": "https://github.com/symfony/http-kernel.git",
"reference": "5e0fc71be03d52cd00c423061cfd300bd6f92a52" "reference": "5f08141850932e8019c01d8988bf3ed6367d2991"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/http-kernel/zipball/5e0fc71be03d52cd00c423061cfd300bd6f92a52", "url": "https://api.github.com/repos/symfony/http-kernel/zipball/5f08141850932e8019c01d8988bf3ed6367d2991",
"reference": "5e0fc71be03d52cd00c423061cfd300bd6f92a52", "reference": "5f08141850932e8019c01d8988bf3ed6367d2991",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -4067,20 +4067,20 @@
], ],
"description": "Symfony HttpKernel Component", "description": "Symfony HttpKernel Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2019-08-26T16:47:42+00:00" "time": "2019-10-07T15:06:41+00:00"
}, },
{ {
"name": "symfony/mime", "name": "symfony/mime",
"version": "v4.3.4", "version": "v4.3.5",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/mime.git", "url": "https://github.com/symfony/mime.git",
"reference": "987a05df1c6ac259b34008b932551353f4f408df" "reference": "32f71570547b91879fdbd9cf50317d556ae86916"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/mime/zipball/987a05df1c6ac259b34008b932551353f4f408df", "url": "https://api.github.com/repos/symfony/mime/zipball/32f71570547b91879fdbd9cf50317d556ae86916",
"reference": "987a05df1c6ac259b34008b932551353f4f408df", "reference": "32f71570547b91879fdbd9cf50317d556ae86916",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -4126,7 +4126,7 @@
"mime", "mime",
"mime-type" "mime-type"
], ],
"time": "2019-08-22T08:16:11+00:00" "time": "2019-09-19T17:00:15+00:00"
}, },
{ {
"name": "symfony/polyfill-ctype", "name": "symfony/polyfill-ctype",
@ -4589,16 +4589,16 @@
}, },
{ {
"name": "symfony/process", "name": "symfony/process",
"version": "v4.3.4", "version": "v4.3.5",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/process.git", "url": "https://github.com/symfony/process.git",
"reference": "e89969c00d762349f078db1128506f7f3dcc0d4a" "reference": "50556892f3cc47d4200bfd1075314139c4c9ff4b"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/process/zipball/e89969c00d762349f078db1128506f7f3dcc0d4a", "url": "https://api.github.com/repos/symfony/process/zipball/50556892f3cc47d4200bfd1075314139c4c9ff4b",
"reference": "e89969c00d762349f078db1128506f7f3dcc0d4a", "reference": "50556892f3cc47d4200bfd1075314139c4c9ff4b",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -4634,7 +4634,7 @@
], ],
"description": "Symfony Process Component", "description": "Symfony Process Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2019-08-26T08:26:39+00:00" "time": "2019-09-26T21:17:10+00:00"
}, },
{ {
"name": "symfony/psr-http-message-bridge", "name": "symfony/psr-http-message-bridge",
@ -4703,16 +4703,16 @@
}, },
{ {
"name": "symfony/routing", "name": "symfony/routing",
"version": "v4.3.4", "version": "v4.3.5",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/routing.git", "url": "https://github.com/symfony/routing.git",
"reference": "ff1049f6232dc5b6023b1ff1c6de56f82bcd264f" "reference": "3b174ef04fe66696524efad1e5f7a6c663d822ea"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/routing/zipball/ff1049f6232dc5b6023b1ff1c6de56f82bcd264f", "url": "https://api.github.com/repos/symfony/routing/zipball/3b174ef04fe66696524efad1e5f7a6c663d822ea",
"reference": "ff1049f6232dc5b6023b1ff1c6de56f82bcd264f", "reference": "3b174ef04fe66696524efad1e5f7a6c663d822ea",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -4775,20 +4775,20 @@
"uri", "uri",
"url" "url"
], ],
"time": "2019-08-26T08:26:39+00:00" "time": "2019-10-04T20:57:10+00:00"
}, },
{ {
"name": "symfony/service-contracts", "name": "symfony/service-contracts",
"version": "v1.1.6", "version": "v1.1.7",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/service-contracts.git", "url": "https://github.com/symfony/service-contracts.git",
"reference": "ea7263d6b6d5f798b56a45a5b8d686725f2719a3" "reference": "ffcde9615dc5bb4825b9f6aed07716f1f57faae0"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/service-contracts/zipball/ea7263d6b6d5f798b56a45a5b8d686725f2719a3", "url": "https://api.github.com/repos/symfony/service-contracts/zipball/ffcde9615dc5bb4825b9f6aed07716f1f57faae0",
"reference": "ea7263d6b6d5f798b56a45a5b8d686725f2719a3", "reference": "ffcde9615dc5bb4825b9f6aed07716f1f57faae0",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -4833,20 +4833,20 @@
"interoperability", "interoperability",
"standards" "standards"
], ],
"time": "2019-08-20T14:44:19+00:00" "time": "2019-09-17T11:12:18+00:00"
}, },
{ {
"name": "symfony/translation", "name": "symfony/translation",
"version": "v4.3.4", "version": "v4.3.5",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/translation.git", "url": "https://github.com/symfony/translation.git",
"reference": "28498169dd334095fa981827992f3a24d50fed0f" "reference": "fe6193b066c457c144333c06aaa869a2d42a167f"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/translation/zipball/28498169dd334095fa981827992f3a24d50fed0f", "url": "https://api.github.com/repos/symfony/translation/zipball/fe6193b066c457c144333c06aaa869a2d42a167f",
"reference": "28498169dd334095fa981827992f3a24d50fed0f", "reference": "fe6193b066c457c144333c06aaa869a2d42a167f",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -4909,20 +4909,20 @@
], ],
"description": "Symfony Translation Component", "description": "Symfony Translation Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2019-08-26T08:55:16+00:00" "time": "2019-09-27T14:37:39+00:00"
}, },
{ {
"name": "symfony/translation-contracts", "name": "symfony/translation-contracts",
"version": "v1.1.6", "version": "v1.1.7",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/translation-contracts.git", "url": "https://github.com/symfony/translation-contracts.git",
"reference": "325b17c24f3ee23cbecfa63ba809c6d89b5fa04a" "reference": "364518c132c95642e530d9b2d217acbc2ccac3e6"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/translation-contracts/zipball/325b17c24f3ee23cbecfa63ba809c6d89b5fa04a", "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/364518c132c95642e530d9b2d217acbc2ccac3e6",
"reference": "325b17c24f3ee23cbecfa63ba809c6d89b5fa04a", "reference": "364518c132c95642e530d9b2d217acbc2ccac3e6",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -4966,20 +4966,20 @@
"interoperability", "interoperability",
"standards" "standards"
], ],
"time": "2019-08-02T12:15:04+00:00" "time": "2019-09-17T11:12:18+00:00"
}, },
{ {
"name": "symfony/var-dumper", "name": "symfony/var-dumper",
"version": "v4.3.4", "version": "v4.3.5",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/var-dumper.git", "url": "https://github.com/symfony/var-dumper.git",
"reference": "641043e0f3e615990a0f29479f9c117e8a6698c6" "reference": "bde8957fc415fdc6964f33916a3755737744ff05"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/641043e0f3e615990a0f29479f9c117e8a6698c6", "url": "https://api.github.com/repos/symfony/var-dumper/zipball/bde8957fc415fdc6964f33916a3755737744ff05",
"reference": "641043e0f3e615990a0f29479f9c117e8a6698c6", "reference": "bde8957fc415fdc6964f33916a3755737744ff05",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -5042,20 +5042,20 @@
"debug", "debug",
"dump" "dump"
], ],
"time": "2019-08-26T08:26:39+00:00" "time": "2019-10-04T19:48:13+00:00"
}, },
{ {
"name": "tightenco/collect", "name": "tightenco/collect",
"version": "v6.1.0", "version": "v6.3.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/tightenco/collect.git", "url": "https://github.com/tightenco/collect.git",
"reference": "8f56fad98222f8fe8c008cbae449f687e331444a" "reference": "7f3f798cb71aa509f5d6e0d1b8f5f4ae0e510869"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/tightenco/collect/zipball/8f56fad98222f8fe8c008cbae449f687e331444a", "url": "https://api.github.com/repos/tightenco/collect/zipball/7f3f798cb71aa509f5d6e0d1b8f5f4ae0e510869",
"reference": "8f56fad98222f8fe8c008cbae449f687e331444a", "reference": "7f3f798cb71aa509f5d6e0d1b8f5f4ae0e510869",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -5084,7 +5084,7 @@
"authors": [ "authors": [
{ {
"name": "Taylor Otwell", "name": "Taylor Otwell",
"email": "taylorotwell@gmail.com" "email": "taylor@laravel.com"
} }
], ],
"description": "Collect - Illuminate Collections as a separate package.", "description": "Collect - Illuminate Collections as a separate package.",
@ -5092,7 +5092,7 @@
"collection", "collection",
"laravel" "laravel"
], ],
"time": "2019-10-02T19:55:13+00:00" "time": "2019-10-05T20:15:22+00:00"
}, },
{ {
"name": "tijsverkoyen/css-to-inline-styles", "name": "tijsverkoyen/css-to-inline-styles",
@ -5266,16 +5266,16 @@
}, },
{ {
"name": "zendframework/zend-diactoros", "name": "zendframework/zend-diactoros",
"version": "2.1.3", "version": "2.1.5",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/zendframework/zend-diactoros.git", "url": "https://github.com/zendframework/zend-diactoros.git",
"reference": "279723778c40164bcf984a2df12ff2c6ec5e61c1" "reference": "6dcf9e760a6b476f3e9d80abbc9ce9c4aa921f9c"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/zendframework/zend-diactoros/zipball/279723778c40164bcf984a2df12ff2c6ec5e61c1", "url": "https://api.github.com/repos/zendframework/zend-diactoros/zipball/6dcf9e760a6b476f3e9d80abbc9ce9c4aa921f9c",
"reference": "279723778c40164bcf984a2df12ff2c6ec5e61c1", "reference": "6dcf9e760a6b476f3e9d80abbc9ce9c4aa921f9c",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -5288,6 +5288,7 @@
"psr/http-message-implementation": "1.0" "psr/http-message-implementation": "1.0"
}, },
"require-dev": { "require-dev": {
"ext-curl": "*",
"ext-dom": "*", "ext-dom": "*",
"ext-libxml": "*", "ext-libxml": "*",
"http-interop/http-factory-tests": "^0.5.0", "http-interop/http-factory-tests": "^0.5.0",
@ -5328,7 +5329,7 @@
"psr", "psr",
"psr-7" "psr-7"
], ],
"time": "2019-07-10T16:13:25+00:00" "time": "2019-10-10T17:38:20+00:00"
} }
], ],
"packages-dev": [ "packages-dev": [
@ -6019,23 +6020,23 @@
}, },
{ {
"name": "justinrainbow/json-schema", "name": "justinrainbow/json-schema",
"version": "5.2.8", "version": "5.2.9",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/justinrainbow/json-schema.git", "url": "https://github.com/justinrainbow/json-schema.git",
"reference": "dcb6e1006bb5fd1e392b4daa68932880f37550d4" "reference": "44c6787311242a979fa15c704327c20e7221a0e4"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/dcb6e1006bb5fd1e392b4daa68932880f37550d4", "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/44c6787311242a979fa15c704327c20e7221a0e4",
"reference": "dcb6e1006bb5fd1e392b4daa68932880f37550d4", "reference": "44c6787311242a979fa15c704327c20e7221a0e4",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": ">=5.3.3" "php": ">=5.3.3"
}, },
"require-dev": { "require-dev": {
"friendsofphp/php-cs-fixer": "~2.2.20", "friendsofphp/php-cs-fixer": "~2.2.20||~2.15.1",
"json-schema/json-schema-test-suite": "1.2.0", "json-schema/json-schema-test-suite": "1.2.0",
"phpunit/phpunit": "^4.8.35" "phpunit/phpunit": "^4.8.35"
}, },
@ -6081,7 +6082,7 @@
"json", "json",
"schema" "schema"
], ],
"time": "2019-01-14T23:55:14+00:00" "time": "2019-09-25T14:49:45+00:00"
}, },
{ {
"name": "mockery/mockery", "name": "mockery/mockery",
@ -6765,16 +6766,16 @@
}, },
{ {
"name": "phpunit/phpunit", "name": "phpunit/phpunit",
"version": "8.4.0", "version": "8.4.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git", "url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "57e5e77b62086033528ee1f4063ae03035f57894" "reference": "366a4a0f2b971fd43b7c351d621e8dd7d7131869"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/57e5e77b62086033528ee1f4063ae03035f57894", "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/366a4a0f2b971fd43b7c351d621e8dd7d7131869",
"reference": "57e5e77b62086033528ee1f4063ae03035f57894", "reference": "366a4a0f2b971fd43b7c351d621e8dd7d7131869",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -6844,7 +6845,7 @@
"testing", "testing",
"xunit" "xunit"
], ],
"time": "2019-10-04T03:12:25+00:00" "time": "2019-10-07T12:57:41+00:00"
}, },
{ {
"name": "roave/security-advisories", "name": "roave/security-advisories",
@ -6852,12 +6853,12 @@
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/Roave/SecurityAdvisories.git", "url": "https://github.com/Roave/SecurityAdvisories.git",
"reference": "3a9ab646603efdccb4f7c4acbb3b36974ef257d8" "reference": "eb59d9f35a47f567ae15e7179d7c666489cd4b85"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/3a9ab646603efdccb4f7c4acbb3b36974ef257d8", "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/eb59d9f35a47f567ae15e7179d7c666489cd4b85",
"reference": "3a9ab646603efdccb4f7c4acbb3b36974ef257d8", "reference": "eb59d9f35a47f567ae15e7179d7c666489cd4b85",
"shasum": "" "shasum": ""
}, },
"conflict": { "conflict": {
@ -6880,7 +6881,6 @@
"contao/core": ">=2,<3.5.39", "contao/core": ">=2,<3.5.39",
"contao/core-bundle": ">=4,<4.4.39|>=4.5,<4.7.5", "contao/core-bundle": ">=4,<4.4.39|>=4.5,<4.7.5",
"contao/listing-bundle": ">=4,<4.4.8", "contao/listing-bundle": ">=4,<4.4.8",
"contao/newsletter-bundle": ">=4,<4.1",
"datadog/dd-trace": ">=0.30,<0.30.2", "datadog/dd-trace": ">=0.30,<0.30.2",
"david-garcia/phpwhois": "<=4.3.1", "david-garcia/phpwhois": "<=4.3.1",
"doctrine/annotations": ">=1,<1.2.7", "doctrine/annotations": ">=1,<1.2.7",
@ -6924,9 +6924,9 @@
"laravel/framework": ">=4,<4.0.99|>=4.1,<=4.1.31|>=4.2,<=4.2.22|>=5,<=5.0.35|>=5.1,<=5.1.46|>=5.2,<=5.2.45|>=5.3,<=5.3.31|>=5.4,<=5.4.36|>=5.5,<5.5.42|>=5.6,<5.6.30", "laravel/framework": ">=4,<4.0.99|>=4.1,<=4.1.31|>=4.2,<=4.2.22|>=5,<=5.0.35|>=5.1,<=5.1.46|>=5.2,<=5.2.45|>=5.3,<=5.3.31|>=5.4,<=5.4.36|>=5.5,<5.5.42|>=5.6,<5.6.30",
"laravel/socialite": ">=1,<1.0.99|>=2,<2.0.10", "laravel/socialite": ">=1,<1.0.99|>=2,<2.0.10",
"league/commonmark": "<0.18.3", "league/commonmark": "<0.18.3",
"magento/magento1ce": "<1.9.4.1", "magento/magento1ce": "<1.9.4.3",
"magento/magento1ee": ">=1.9,<1.14.4.1", "magento/magento1ee": ">=1,<1.14.4.3",
"magento/product-community-edition": ">=2,<2.2.8|>=2.3,<2.3.1", "magento/product-community-edition": ">=2,<2.2.10|>=2.3,<2.3.3",
"monolog/monolog": ">=1.8,<1.12", "monolog/monolog": ">=1.8,<1.12",
"namshi/jose": "<2.2", "namshi/jose": "<2.2",
"onelogin/php-saml": "<2.10.4", "onelogin/php-saml": "<2.10.4",
@ -7061,7 +7061,7 @@
} }
], ],
"description": "Prevents installation of composer packages with known security vulnerabilities: no API, simply require it", "description": "Prevents installation of composer packages with known security vulnerabilities: no API, simply require it",
"time": "2019-09-26T17:56:56+00:00" "time": "2019-10-09T14:04:58+00:00"
}, },
{ {
"name": "sebastian/code-unit-reverse-lookup", "name": "sebastian/code-unit-reverse-lookup",
@ -7773,7 +7773,7 @@
}, },
{ {
"name": "symfony/filesystem", "name": "symfony/filesystem",
"version": "v4.3.4", "version": "v4.3.5",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/filesystem.git", "url": "https://github.com/symfony/filesystem.git",

View File

@ -27,7 +27,7 @@ use FireflyIII\Providers\ImportServiceProvider;
return [ return [
'name' => envNonEmpty('APP_NAME', 'Firefly III'), 'name' => envNonEmpty('APP_NAME', 'Firefly III'),
'env' => envNonEmpty('APP_ENV', 'production'), 'env' => envNonEmpty('APP_ENV', 'local'),
'debug' => env('APP_DEBUG', false), 'debug' => env('APP_DEBUG', false),
'url' => envNonEmpty('APP_URL', 'http://localhost'), 'url' => envNonEmpty('APP_URL', 'http://localhost'),
'timezone' => envNonEmpty('TZ', 'UTC'), 'timezone' => envNonEmpty('TZ', 'UTC'),

View File

@ -84,7 +84,7 @@ return [
'servers' => [ 'servers' => [
[ [
'host' => env('MEMCACHED_HOST', '127.0.0.1'), 'host' => env('MEMCACHED_HOST', '127.0.0.1'),
'port' => env('MEMCACHED_PORT', 11211), 'port' => (int)env('MEMCACHED_PORT', 11211),
'weight' => 100, 'weight' => 100,
], ],
], ],

View File

@ -125,8 +125,8 @@ return [
'is_demo_site' => false, 'is_demo_site' => false,
], ],
'encryption' => null === env('USE_ENCRYPTION') || env('USE_ENCRYPTION') === true, 'encryption' => null === env('USE_ENCRYPTION') || env('USE_ENCRYPTION') === true,
'version' => '4.8.1.4', 'version' => '4.8.1.5',
'api_version' => '0.10.3', 'api_version' => '0.10.4',
'db_version' => 11, 'db_version' => 11,
'maxUploadSize' => 15242880, 'maxUploadSize' => 15242880,
'send_error_message' => env('SEND_ERROR_MESSAGE', true), 'send_error_message' => env('SEND_ERROR_MESSAGE', true),
@ -135,7 +135,6 @@ return [
'demo_username' => env('DEMO_USERNAME', ''), 'demo_username' => env('DEMO_USERNAME', ''),
'demo_password' => env('DEMO_PASSWORD', ''), 'demo_password' => env('DEMO_PASSWORD', ''),
'is_sandstorm' => env('IS_SANDSTORM', 'unknown'), 'is_sandstorm' => env('IS_SANDSTORM', 'unknown'),
'is_docker' => env('IS_DOCKER', 'unknown'),
'bunq_use_sandbox' => env('BUNQ_USE_SANDBOX', false), 'bunq_use_sandbox' => env('BUNQ_USE_SANDBOX', false),
'fixer_api_key' => env('FIXER_API_KEY', ''), 'fixer_api_key' => env('FIXER_API_KEY', ''),
'mapbox_api_key' => env('MAPBOX_API_KEY', ''), 'mapbox_api_key' => env('MAPBOX_API_KEY', ''),
@ -519,8 +518,8 @@ return [
'default_currency' => 'EUR', 'default_currency' => 'EUR',
'default_language' => 'en_US', 'default_language' => 'en_US',
'search_modifiers' => ['amount_is', 'amount', 'amount_max', 'amount_min', 'amount_less', 'amount_more', 'source', 'destination', 'category', 'search_modifiers' => ['amount_is', 'amount', 'amount_max', 'amount_min', 'amount_less', 'amount_more', 'source', 'destination', 'category',
'budget', 'bill', 'type', 'date', 'date_before', 'date_after', 'on', 'before', 'after', 'from', 'to', 'tag', 'created_at', 'budget', 'bill', 'type', 'date', 'date_before', 'date_after', 'on', 'before', 'after', 'from', 'to', 'tag', 'created_on',
'updated_at'], 'updated_on'],
// TODO notes has_attachments // TODO notes has_attachments
'cer_providers' => [ 'cer_providers' => [

View File

@ -22,6 +22,7 @@
"@johmun/vue-tags-input": "^2.0.1", "@johmun/vue-tags-input": "^2.0.1",
"font-awesome": "^4.7.0", "font-awesome": "^4.7.0",
"jquery": "^3.1.1", "jquery": "^3.1.1",
"uiv": "^0.31.5" "uiv": "^0.31.5",
"vue-i18n": "^8.14.1"
} }
} }

2
public/v1/js/app.js vendored

File diff suppressed because one or more lines are too long

View File

@ -43,7 +43,7 @@ $(function () {
* Downloads some JSON and responds to its content to see what the status is of the current import job. * Downloads some JSON and responds to its content to see what the status is of the current import job.
*/ */
function checkJobJSONStatus() { function checkJobJSONStatus() {
console.log('In checkJobJSONStatus()'); //console.log('In checkJobJSONStatus()');
if (jobFailed === false) { if (jobFailed === false) {
$.getJSON(jobStatusUri).done(reportJobJSONDone).fail(reportJobJSONFailure); $.getJSON(jobStatusUri).done(reportJobJSONDone).fail(reportJobJSONFailure);
} }
@ -58,8 +58,8 @@ function checkJobJSONStatus() {
* @param data * @param data
*/ */
function reportJobJSONDone(data) { function reportJobJSONDone(data) {
console.log('In reportJobJSONDone() with status "' + data.status + '"'); //console.log('In reportJobJSONDone() with status "' + data.status + '"');
console.log(data); //console.log(data);
switch (data.status) { switch (data.status) {
case "ready_to_run": case "ready_to_run":
if (startCount > 0) { if (startCount > 0) {
@ -87,7 +87,7 @@ function reportJobJSONDone(data) {
showJobResults(data); showJobResults(data);
break; break;
default: default:
console.warn('No specific action for status ' + data.status); //console.warn('No specific action for status ' + data.status);
showProgressBox(data.status); showProgressBox(data.status);
recheckJobJSONStatus(); recheckJobJSONStatus();
@ -99,7 +99,7 @@ function reportJobJSONDone(data) {
* @param data * @param data
*/ */
function showJobResults(data) { function showJobResults(data) {
console.log('In showJobResults()'); //console.log('In showJobResults()');
// hide all boxes. // hide all boxes.
$('.statusbox').hide(); $('.statusbox').hide();
@ -127,7 +127,7 @@ function showJobResults(data) {
* Will refresh and get job status. * Will refresh and get job status.
*/ */
function recheckJobJSONStatus() { function recheckJobJSONStatus() {
console.log('In recheckJobJSONStatus()'); //console.log('In recheckJobJSONStatus()');
if (maxLoops !== 0 && totalLoops < maxLoops && jobFailed === false) { if (maxLoops !== 0 && totalLoops < maxLoops && jobFailed === false) {
timeOutId = setTimeout(checkJobJSONStatus, checkNextInterval); timeOutId = setTimeout(checkJobJSONStatus, checkNextInterval);
} }
@ -206,7 +206,7 @@ function reportJobJSONFailure(xhr, status, error) {
* *
*/ */
function showProgressBox(status) { function showProgressBox(status) {
console.log('In showProgressBox()'); //console.log('In showProgressBox()');
// hide fatal error box: // hide fatal error box:
$('.fatal_error').hide(); $('.fatal_error').hide();
@ -242,7 +242,7 @@ function showProgressBox(status) {
* @param error * @param error
*/ */
function reportJobPOSTFailure(xhr, status, error) { function reportJobPOSTFailure(xhr, status, error) {
console.log('In reportJobPOSTFailure()'); //console.log('In reportJobPOSTFailure()');
// cancel checking again for job status: // cancel checking again for job status:
clearTimeout(timeOutId); clearTimeout(timeOutId);
if (reportedError === false) { if (reportedError === false) {

View File

@ -6,6 +6,7 @@
[![License](https://img.shields.io/github/license/firefly-iii/firefly-iii.svg?style=flat-square])](https://www.gnu.org/licenses/agpl-3.0.html) [![License](https://img.shields.io/github/license/firefly-iii/firefly-iii.svg?style=flat-square])](https://www.gnu.org/licenses/agpl-3.0.html)
[![Donate using Paypal](https://img.shields.io/badge/donate-PayPal-green?logo=paypal)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=44UKUT455HUFA) [![Donate using Paypal](https://img.shields.io/badge/donate-PayPal-green?logo=paypal)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=44UKUT455HUFA)
[![Donate using Patreon](https://img.shields.io/badge/donate-%40JC5-green?logo=patreon)](https://www.patreon.com/jc5) [![Donate using Patreon](https://img.shields.io/badge/donate-%40JC5-green?logo=patreon)](https://www.patreon.com/jc5)
[![Donate using GitHub](https://img.shields.io/badge/donate-GitHub-green?logo=github&style=flat)](https://github.com/sponsors/JC5)
* [Introduction](#introduction) * [Introduction](#introduction)
@ -37,7 +38,7 @@ Personal financial management is pretty difficult, and everybody has their own a
By keeping track of your expenses and your income you can budget accordingly and save money. Stop living from paycheck to paycheck but give yourself the financial wiggle room you need. By keeping track of your expenses and your income you can budget accordingly and save money. Stop living from paycheck to paycheck but give yourself the financial wiggle room you need.
You can read more about this in the [official documentation](https://firefly-iii.readthedocs.io/en/latest/index.html). You can read more about this in the [official documentation](https://docs.firefly-iii.org/).
### Features ### Features
Firefly III is pretty feature packed. Some important stuff first: Firefly III is pretty feature packed. Some important stuff first:
@ -49,38 +50,38 @@ Firefly III is pretty feature packed. Some important stuff first:
The most exciting features are: The most exciting features are:
* Create [recurring transactions to manage your money](http://docs.firefly-iii.org/en/latest/advanced/recurring.html) * Create [recurring transactions to manage your money](https://docs.firefly-iii.org/advanced-concepts/recurring)
* [Rule based transaction handling](http://docs.firefly-iii.org/en/latest/advanced/rules.html) with the ability to create your own rules * [Rule based transaction handling](https://docs.firefly-iii.org/advanced-concepts/rules) with the ability to create your own rules
* Import data from external systems * Import data from external systems
* [FinTS](http://docs.firefly-iii.org/en/latest/import/fints.html) * [FinTS](https://docs.firefly-iii.org/importing-data/fints)
* [bunq](http://docs.firefly-iii.org/en/latest/import/bunq.html) * [bunq](https://docs.firefly-iii.org/importing-data/bunq)
* [Spectre](http://docs.firefly-iii.org/en/latest/import/spectre.html) (offering thousands of connected banks) * [Spectre](https://docs.firefly-iii.org/importing-data/spectre) (offering thousands of connected banks)
* [CSV files](http://docs.firefly-iii.org/en/latest/import/csv.html) * [CSV files](https://docs.firefly-iii.org/importing-data/csv)
* [YNAB](http://docs.firefly-iii.org/en/latest/import/ynab.html) * [YNAB](https://docs.firefly-iii.org/importing-data/ynab)
Then the things that make you go "yeah OK, makes sense". Then the things that make you go "yeah OK, makes sense".
* A [double-entry](https://en.wikipedia.org/wiki/Double-entry_bookkeeping_system) bookkeeping system * A [double-entry](https://en.wikipedia.org/wiki/Double-entry_bookkeeping_system) bookkeeping system
* You can store, edit and remove [withdrawals, deposits and transfers](http://docs.firefly-iii.org/en/latest/concepts/transactions.html). This allows you full financial management * You can store, edit and remove [withdrawals, deposits and transfers](https://docs.firefly-iii.org/concepts/transactions). This allows you full financial management
* You can manage [different types of accounts](http://docs.firefly-iii.org/en/latest/concepts/accounts.html) * You can manage [different types of accounts](https://docs.firefly-iii.org/concepts/accounts)
* Asset accounts * Asset accounts
* Shared asset accounts (household accounts) * Shared asset accounts (household accounts)
* Saving accounts * Saving accounts
* Credit cards * Credit cards
* Loans, mortgages * Loans, mortgages
* It's possible to create, change and manage money [using budgets](http://docs.firefly-iii.org/en/latest/concepts/budgets.html) * It's possible to create, change and manage money [using budgets](https://docs.firefly-iii.org/concepts/budgets)
* Organize transactions [using categories](http://docs.firefly-iii.org/en/latest/concepts/categories.html) * Organize transactions [using categories](https://docs.firefly-iii.org/concepts/categories)
* Save towards a goal using [piggy banks](http://docs.firefly-iii.org/en/latest/advanced/piggies.html) * Save towards a goal using [piggy banks](https://docs.firefly-iii.org/advanced-concepts/piggies)
* Predict and anticipate [bills](http://docs.firefly-iii.org/en/latest/advanced/bills.html) * Predict and anticipate [bills](https://docs.firefly-iii.org/advanced-concepts/bills)
* View [income and expense reports](http://docs.firefly-iii.org/en/latest/advanced/reports.html) * View [income and expense reports](https://docs.firefly-iii.org/advanced-concepts/reports)
* Organize expenses [using tags](http://docs.firefly-iii.org/en/latest/concepts/tags.html) * Organize expenses [using tags](https://docs.firefly-iii.org/concepts/tags)
And the things you would hope for but not expect: And the things you would hope for but not expect:
* 2 factor authentication for extra security 🔒 * 2 factor authentication for extra security 🔒
* Supports [any currency you want](http://docs.firefly-iii.org/en/latest/concepts/currencies.html), including crypto currencies such as ₿itcoin and Ξthereum * Supports [any currency you want](https://docs.firefly-iii.org/concepts/currencies), including crypto currencies such as ₿itcoin and Ξthereum
* There is a [Docker image](http://docs.firefly-iii.org/en/latest/installation/docker.html), a [Sandstorm.io grain](http://docs.firefly-iii.org/en/latest/installation/hosted.html) and an [Heroku script](http://docs.firefly-iii.org/en/latest/installation/hosted.html). * There is a [Docker image](https://docs.firefly-iii.org/installation/docker), a [Sandstorm.io grain](https://docs.firefly-iii.org/installation/third_parties) and an [Heroku script](https://docs.firefly-iii.org/installation/third_parties).
* Lots of help text in case you don't get it * Lots of help text in case you don't get it.
And to organise everything: And to organise everything:
@ -88,7 +89,7 @@ And to organise everything:
* Easy navigation through your records * Easy navigation through your records
* Browse back and forth to see previous months or even years * Browse back and forth to see previous months or even years
* Lots of charts because we all love them * Lots of charts because we all love them
* If you feel youre missing something you [can just ask me](http://docs.firefly-iii.org/en/latest/contact/contact.html) and Ill add it! * If you feel youre missing something you [can just ask me](https://docs.firefly-iii.org/contact/contact) and Ill add it!
### Who is it for? ### Who is it for?
This application is for people who want to track their finances, keep an eye on their money **without having to upload their financial records to the cloud**. You're a bit tech-savvy, you like open source software and you don't mind tinkering with (self-hosted) servers. This application is for people who want to track their finances, keep an eye on their money **without having to upload their financial records to the cloud**. You're a bit tech-savvy, you like open source software and you don't mind tinkering with (self-hosted) servers.
@ -96,10 +97,10 @@ This application is for people who want to track their finances, keep an eye on
## Get started ## Get started
There are many ways to run Firefly III There are many ways to run Firefly III
1. There is a [demo site](https://demo.firefly-iii.org) with an example financial administration already present. 1. There is a [demo site](https://demo.firefly-iii.org) with an example financial administration already present.
2. You can [install it on your server](https://firefly-iii.readthedocs.io/en/latest/installation/server.html). 2. You can [install it on your server](https://docs.firefly-iii.org/installation/self_hosted).
3. You can [run it using Docker](https://firefly-iii.readthedocs.io/en/latest/installation/docker.html). 3. You can [run it using Docker](https://docs.firefly-iii.org/installation/docker).
4. You can [deploy to Heroku](https://heroku.com/deploy?template=https://github.com/firefly-iii/firefly-iii/tree/master). 4. You can [deploy to Heroku](https://heroku.com/deploy?template=https://github.com/firefly-iii/firefly-iii/tree/master).
* Please read the [considerations when using Heroku](https://firefly-iii.readthedocs.io/en/latest/installation/hosted.html#considerations-when-using-heroku) first though. * Please read the [considerations when using Heroku](https://docs.firefly-iii.org/installation/third_parties#considerations-when-using-heroku) first though.
5. You can [deploy to Sandstorm.io](https://apps.sandstorm.io/app/uws252ya9mep4t77tevn85333xzsgrpgth8q4y1rhknn1hammw70). 5. You can [deploy to Sandstorm.io](https://apps.sandstorm.io/app/uws252ya9mep4t77tevn85333xzsgrpgth8q4y1rhknn1hammw70).
* Note that you must have a paid Sandstorm account for this to work, or you must self-host your Sandstorm server. * Note that you must have a paid Sandstorm account for this to work, or you must self-host your Sandstorm server.
6. You can [install it using Softaculous](https://softaculous.com/). These guys even have made [another demo site](https://www.softaculous.com/softaculous/apps/others/Firefly_III)! 6. You can [install it using Softaculous](https://softaculous.com/). These guys even have made [another demo site](https://www.softaculous.com/softaculous/apps/others/Firefly_III)!
@ -108,14 +109,14 @@ There are many ways to run Firefly III
9. *Even more options are on the way!* 9. *Even more options are on the way!*
### Update your instance ### Update your instance
Make sure you check for updates regularly. Your Firefly III instance will ask you to do this. [Upgrade instructions](https://firefly-iii.readthedocs.io/en/latest/installation/upgrading.html) can be found in the [official documentation](https://firefly-iii.readthedocs.io/en/latest/index.html). Make sure you check for updates regularly. Your Firefly III instance will ask you to do this. [Upgrade instructions](https://docs.firefly-iii.org/advanced-installation/upgrade) can be found in the [official documentation](https://docs.firefly-iii.org/).
## Contribute ## Contribute
Your help is always welcome! Feel free to open issues, ask questions, talk about it and discuss this tool. I've created several social media accounts and I invite you to follow them, tweet at them and post to them. There's [reddit](https://www.reddit.com/r/FireflyIII/) and [Twitter](https://twitter.com/Firefly_III). It's not very active but it's a start! Your help is always welcome! Feel free to open issues, ask questions, talk about it and discuss this tool. I've created several social media accounts and I invite you to follow them, tweet at them and post to them. There's [reddit](https://www.reddit.com/r/FireflyIII/) and [Twitter](https://twitter.com/Firefly_III).
Of course, there are some [contributing guidelines](https://github.com/firefly-iii/firefly-iii/blob/master/.github/contributing.md) and a [code of conduct](https://github.com/firefly-iii/firefly-iii/blob/master/.github/code_of_conduct.md), which I invite you to check out. Of course, there are some [contributing guidelines](https://github.com/firefly-iii/firefly-iii/blob/master/.github/contributing.md) and a [code of conduct](https://github.com/firefly-iii/firefly-iii/blob/master/.github/code_of_conduct.md), which I invite you to check out.
I can always use your help [squashing bugs](https://firefly-iii.readthedocs.io/en/latest/support/contribute.html#bugs), thinking about [new features](https://firefly-iii.readthedocs.io/en/latest/support/contribute.html#feature-requests) or [translating Firefly III](https://firefly-iii.readthedocs.io/en/latest/support/contribute.html#translations) into other languages. I can always use your help [squashing bugs](https://docs.firefly-iii.org/support/contribute#bugs), thinking about [new features](https://docs.firefly-iii.org/support/contribute#feature-requests) or [translating Firefly III](https://docs.firefly-iii.org/support/contribute#translations) into other languages.
For all other contributions, see below. For all other contributions, see below.
@ -125,7 +126,7 @@ Firefly III should give you **insight** into and **control** over your finances.
But you get the idea: this is your money. These are your expenses. Stop them from controlling you. I built this tool because I started to dislike money. Having it, not having, paying bills with it, etc. But no more. I want to feel "safe", whatever my balance is. And I hope this tool can help. I know it helps me. But you get the idea: this is your money. These are your expenses. Stop them from controlling you. I built this tool because I started to dislike money. Having it, not having, paying bills with it, etc. But no more. I want to feel "safe", whatever my balance is. And I hope this tool can help. I know it helps me.
## Contact ## Contact
You can contact me at [thegrumpydictator@gmail.com](mailto:thegrumpydictator@gmail.com), you may open an issue or contact me through the various social media pages there are: [reddit](https://www.reddit.com/r/FireflyIII/), [Twitter](https://twitter.com/Firefly_III) and [Facebook](https://www.facebook.com/FireflyIII/). You can contact me at [thegrumpydictator@gmail.com](mailto:thegrumpydictator@gmail.com), you may open an issue or contact me through the various social media pages there are: [reddit](https://www.reddit.com/r/FireflyIII/) and [Twitter](https://twitter.com/Firefly_III).
Over time, [many people have contributed to Firefly III](https://github.com/firefly-iii/firefly-iii/graphs/contributors). Over time, [many people have contributed to Firefly III](https://github.com/firefly-iii/firefly-iii/graphs/contributors).
@ -150,6 +151,8 @@ If you like Firefly III and if it helps you save lots of money, why not send me
OK that was a joke. You can donate using [PayPal](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=44UKUT455HUFA) or [Patreon](https://www.patreon.com/jc5). OK that was a joke. You can donate using [PayPal](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=44UKUT455HUFA) or [Patreon](https://www.patreon.com/jc5).
I am very proud to be a part of the **[GitHub Sponsors Program](https://github.com/sponsors/JC5)**. Use their program if you can; they'll double your donation!
Thank you for considering donating to Firefly III! Thank you for considering donating to Firefly III!
### Alternatives ### Alternatives

View File

@ -18,26 +18,15 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
import CustomAttachments from "./components/transactions/CustomAttachments"; import Vue from 'vue'
import VueI18n from 'vue-i18n'
/**
* First we will load all of this project's JavaScript dependencies which
* includes Vue and other libraries. It is a great starting point when
* building robust, powerful web applications using Vue and Laravel.
*/
require('./bootstrap');
window.Vue = require('vue');
import * as uiv from 'uiv'; import * as uiv from 'uiv';
import CustomAttachments from "./components/transactions/CustomAttachments";
Vue.use(uiv);
import CreateTransaction from './components/transactions/CreateTransaction'; import CreateTransaction from './components/transactions/CreateTransaction';
import EditTransaction from './components/transactions/EditTransaction'; import EditTransaction from './components/transactions/EditTransaction';
import Clients from './components/passport/Clients'; import Clients from './components/passport/Clients';
import AuthorizedClients from "./components/passport/AuthorizedClients"; import AuthorizedClients from "./components/passport/AuthorizedClients";
import PersonalAccessTokens from "./components/passport/PersonalAccessTokens"; import PersonalAccessTokens from "./components/passport/PersonalAccessTokens";
import Budget from "./components/transactions/Budget";
import CustomDate from "./components/transactions/CustomDate"; import CustomDate from "./components/transactions/CustomDate";
import CustomString from "./components/transactions/CustomString"; import CustomString from "./components/transactions/CustomString";
import CustomTextarea from "./components/transactions/CustomTextarea"; import CustomTextarea from "./components/transactions/CustomTextarea";
@ -52,6 +41,22 @@ import Amount from "./components/transactions/Amount";
import ForeignAmountSelect from "./components/transactions/ForeignAmountSelect"; import ForeignAmountSelect from "./components/transactions/ForeignAmountSelect";
import TransactionType from "./components/transactions/TransactionType"; import TransactionType from "./components/transactions/TransactionType";
import AccountSelect from "./components/transactions/AccountSelect"; import AccountSelect from "./components/transactions/AccountSelect";
import Budget from "./components/transactions/Budget";
/**
* First we will load all of this project's JavaScript dependencies which
* includes Vue and other libraries. It is a great starting point when
* building robust, powerful web applications using Vue and Laravel.
*/
require('./bootstrap');
Vue.use(VueI18n);
window.Vue = Vue;
Vue.use(uiv);
// components for create and edit transactions. // components for create and edit transactions.
Vue.component('budget', Budget); Vue.component('budget', Budget);
@ -82,7 +87,28 @@ Vue.component('passport-personal-access-tokens', PersonalAccessTokens);
Vue.component('create-transaction', CreateTransaction); Vue.component('create-transaction', CreateTransaction);
Vue.component('edit-transaction', EditTransaction); Vue.component('edit-transaction', EditTransaction);
// Create VueI18n instance with options
const i18n = new VueI18n({
locale: document.documentElement.lang, // set locale
fallbackLocale: 'en',
messages: {
'cs': require('./locales/cs.json'),
'de': require('./locales/de.json'),
'en': require('./locales/en.json'),
'es': require('./locales/es.json'),
'fr': require('./locales/fr.json'),
'hu': require('./locales/hu.json'),
'id': require('./locales/id.json'),
'it': require('./locales/it.json'),
'nl': require('./locales/nl.json'),
'no': require('./locales/no.json'),
'pl': require('./locales/pl.json'),
'pt-br': require('./locales/pt-br.json'),
'ro': require('./locales/ro.json'),
'ru': require('./locales/ru.json'),
'zh': require('./locales/zh.json'),
'zh-tw': require('./locales/zh-tw.json'),
}
});
const app = new Vue({ new Vue({i18n}).$mount('#app');
el: '#app'
});

View File

@ -18,7 +18,6 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
/* TODO REMOVE ME */
window._ = require('lodash'); window._ = require('lodash');
/** /**

View File

@ -18,7 +18,6 @@
- along with this program. If not, see <https://www.gnu.org/licenses/>. - along with this program. If not, see <https://www.gnu.org/licenses/>.
--> -->
<!-- TODO REMOVE ME -->
<template> <template>
<div class="container"> <div class="container">
<div class="row"> <div class="row">

View File

@ -0,0 +1,43 @@
<!--
- SomeTestComponent.vue
- Copyright (c) 2019 thegrumpydictator@gmail.com
-
- This file is part of Firefly III (https://github.com/firefly-iii).
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as
- published by the Free Software Foundation, either version 3 of the
- License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <https://www.gnu.org/licenses/>.
-->
<template>
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">Test Component</div>
<div class="panel-body">
<p>{{ $t("firefly.welcome_back") }}</p>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
mounted() {
console.log('Component mounted.')
}
}
</script>

View File

@ -18,7 +18,6 @@
- along with this program. If not, see <https://www.gnu.org/licenses/>. - along with this program. If not, see <https://www.gnu.org/licenses/>.
--> -->
<!-- TODO REMOVE ME -->
<style scoped> <style scoped>
.action-link { .action-link {
cursor: pointer; cursor: pointer;
@ -163,8 +162,7 @@
Here is your new personal access token. This is the only time it will be shown so don't lose it! Here is your new personal access token. This is the only time it will be shown so don't lose it!
You may now use this token to make API requests. You may now use this token to make API requests.
</p> </p>
<pre><textarea id="tokenHidden" style="width:100%;" rows="20" class="form-control">{{ accessToken }}</textarea></pre>
<pre><code>{{ accessToken }}</code></pre>
</div> </div>
<!-- Modal Actions --> <!-- Modal Actions -->

View File

@ -101,8 +101,6 @@
this.target = this.$refs.input; this.target = this.$refs.input;
let types = this.allowedTypes.join(','); let types = this.allowedTypes.join(',');
this.name = this.accountName; this.name = this.accountName;
// console.log('Mounted Types:');
// console.log(this.allowedTypes);
this.accountAutoCompleteURI = document.getElementsByTagName('base')[0].href + "json/accounts?types=" + types + "&search="; this.accountAutoCompleteURI = document.getElementsByTagName('base')[0].href + "json/accounts?types=" + types + "&search=";
this.triggerTransactionType(); this.triggerTransactionType();
}, },
@ -115,7 +113,6 @@
let types = this.accountTypeFilters.join(','); let types = this.accountTypeFilters.join(',');
if (0 === this.accountTypeFilters.length) { if (0 === this.accountTypeFilters.length) {
types = this.defaultAccountTypeFilters.join(','); types = this.defaultAccountTypeFilters.join(',');
// console.log('types was empty: ' + types);
} }
this.accountAutoCompleteURI = document.getElementsByTagName('base')[0].href + "json/accounts?types=" + types + "&search="; this.accountAutoCompleteURI = document.getElementsByTagName('base')[0].href + "json/accounts?types=" + types + "&search=";
} }

View File

@ -25,7 +25,7 @@
<input type="number" ref="amount" :value="value" @input="handleInput" step="any" <input type="number" ref="amount" :value="value" @input="handleInput" step="any"
class="form-control" class="form-control"
name="amount[]" name="amount[]"
title="amount" autocomplete="off" placeholder="Amount"> title="amount" autocomplete="off" v-bind:placeholder="$t('firefly.amount')">
<ul class="list-unstyled" v-for="error in this.error"> <ul class="list-unstyled" v-for="error in this.error">
<li class="text-danger">{{ error }}</li> <li class="text-danger">{{ error }}</li>
</ul> </ul>

View File

@ -40,7 +40,7 @@
<script> <script>
export default { export default {
name: "Budget", name: "Budget",
props: ['transactionType', 'value', 'error'], props: ['transactionType', 'value', 'error','no_budget'],
mounted() { mounted() {
this.loadBudgets(); this.loadBudgets();
// console.log('budget value'); // console.log('budget value');
@ -63,7 +63,7 @@
axios.get(URI, {}).then((res) => { axios.get(URI, {}).then((res) => {
this.budgets = [ this.budgets = [
{ {
name: '(no budget)', name: this.no_budget,
id: 0, id: 0,
} }
]; ];

View File

@ -27,14 +27,14 @@
:value="value" :value="value"
@input="handleInput" @input="handleInput"
type="text" type="text"
placeholder="Category" v-bind:placeholder="$t('firefly.category')"
autocomplete="off" autocomplete="off"
data-role="input" data-role="input"
v-on:keypress="handleEnter" v-on:keypress="handleEnter"
class="form-control" class="form-control"
v-on:submit.prevent v-on:submit.prevent
name="category[]" name="category[]"
title="Category"> v-bind:title="$t('firefly.category')">
<span class="input-group-btn"> <span class="input-group-btn">
<button <button
v-on:click="clearCategory" v-on:click="clearCategory"

View File

@ -24,9 +24,9 @@
<div class="row" v-if="error_message !== ''"> <div class="row" v-if="error_message !== ''">
<div class="col-lg-12"> <div class="col-lg-12">
<div class="alert alert-danger alert-dismissible" role="alert"> <div class="alert alert-danger alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span <button type="button" class="close" data-dismiss="alert" v-bind:aria-label="$t('firefly.close')"><span
aria-hidden="true">&times;</span></button> aria-hidden="true">&times;</span></button>
<strong>Error!</strong> {{ error_message }} <strong>{{ $t("firefly.flash_error") }}</strong> {{ error_message }}
</div> </div>
</div> </div>
</div> </div>
@ -34,9 +34,9 @@
<div class="row" v-if="success_message !== ''"> <div class="row" v-if="success_message !== ''">
<div class="col-lg-12"> <div class="col-lg-12">
<div class="alert alert-success alert-dismissible" role="alert"> <div class="alert alert-success alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span <button type="button" class="close" data-dismiss="alert" v-bind:aria-label="$t('firefly.close')"><span
aria-hidden="true">&times;</span></button> aria-hidden="true">&times;</span></button>
<strong>Success!</strong> <span v-html="success_message"></span> <strong>{{ $t("firefly.flash_success") }}</strong> <span v-html="success_message"></span>
</div> </div>
</div> </div>
</div> </div>
@ -45,7 +45,7 @@
<div class="box"> <div class="box">
<div class="box-header with-border"> <div class="box-header with-border">
<h3 class="box-title"> <h3 class="box-title">
Description of the split transaction {{ $t('firefly.split_title_help')}}
</h3> </h3>
</div> </div>
<div class="box-body"> <div class="box-body">
@ -64,8 +64,8 @@
<div class="box"> <div class="box">
<div class="box-header with-border"> <div class="box-header with-border">
<h3 class="box-title splitTitle"> <h3 class="box-title splitTitle">
<span v-if="transactions.length > 1">Split {{ index+1 }} / {{ transactions.length }}</span> <span v-if="transactions.length > 1">{{ $t('firefly.split')}} {{ index+1 }} / {{ transactions.length }}</span>
<span v-if="transactions.length === 1">Transaction information</span> <span v-if="transactions.length === 1">{{ $t('firefly.transaction_journal_information') }}</span>
</h3> </h3>
<div class="box-tools pull-right" v-if="transactions.length > 1" x> <div class="box-tools pull-right" v-if="transactions.length > 1" x>
<button type="button" v-on:click="deleteTransaction(index, $event)" class="btn btn-xs btn-danger"><i <button type="button" v-on:click="deleteTransaction(index, $event)" class="btn btn-xs btn-danger"><i
@ -83,7 +83,7 @@
</transaction-description> </transaction-description>
<account-select <account-select
inputName="source[]" inputName="source[]"
title="Source account" v-bind:title="$t('firefly.source_account')"
:accountName="transaction.source_account.name" :accountName="transaction.source_account.name"
:accountTypeFilters="transaction.source_account.allowed_types" :accountTypeFilters="transaction.source_account.allowed_types"
:defaultAccountTypeFilters="transaction.source_account.default_allowed_types" :defaultAccountTypeFilters="transaction.source_account.default_allowed_types"
@ -95,7 +95,7 @@
></account-select> ></account-select>
<account-select <account-select
inputName="destination[]" inputName="destination[]"
title="Destination account" v-bind:title="$t('firefly.destination_account')"
:accountName="transaction.destination_account.name" :accountName="transaction.destination_account.name"
:accountTypeFilters="transaction.destination_account.allowed_types" :accountTypeFilters="transaction.destination_account.allowed_types"
:defaultAccountTypeFilters="transaction.destination_account.default_allowed_types" :defaultAccountTypeFilters="transaction.destination_account.default_allowed_types"
@ -135,6 +135,7 @@
v-model="transaction.foreign_amount" v-model="transaction.foreign_amount"
:transactionType="transactionType" :transactionType="transactionType"
:error="transaction.errors.foreign_amount" :error="transaction.errors.foreign_amount"
v-bind:title="$t('form.foreign_amount')"
></foreign-amount> ></foreign-amount>
</div> </div>
<div class="col-lg-4"> <div class="col-lg-4">
@ -142,6 +143,7 @@
:transactionType="transactionType" :transactionType="transactionType"
v-model="transaction.budget" v-model="transaction.budget"
:error="transaction.errors.budget_id" :error="transaction.errors.budget_id"
:no_budget="$t('firefly.none_in_select_list')"
></budget> ></budget>
<category <category
:transactionType="transactionType" :transactionType="transactionType"
@ -152,6 +154,7 @@
:transactionType="transactionType" :transactionType="transactionType"
v-model="transaction.piggy_bank" v-model="transaction.piggy_bank"
:error="transaction.errors.piggy_bank" :error="transaction.errors.piggy_bank"
:no_piggy_bank="$t('firefly.no_piggy_bank')"
></piggy-bank> ></piggy-bank>
<tags <tags
v-model="transaction.tags" v-model="transaction.tags"
@ -165,7 +168,7 @@
</div> </div>
</div> </div>
<div class="box-footer" v-if="transactions.length-1 === index"> <div class="box-footer" v-if="transactions.length-1 === index">
<button class="split_add_btn btn btn-primary" type="button" @click="addTransactionToArray">Add another split</button> <button class="split_add_btn btn btn-primary" type="button" @click="addTransactionToArray">{{ $t('firefly.add_another_split') }}</button>
</div> </div>
</div> </div>
</div> </div>
@ -176,26 +179,26 @@
<div class="box"> <div class="box">
<div class="box-header with-border"> <div class="box-header with-border">
<h3 class="box-title"> <h3 class="box-title">
Submission {{ $t('firefly.submission') }}
</h3> </h3>
</div> </div>
<div class="box-body"> <div class="box-body">
<div class="checkbox"> <div class="checkbox">
<label> <label>
<input v-model="createAnother" name="create_another" type="checkbox"> <input v-model="createAnother" name="create_another" type="checkbox">
After storing, return here to create another one. {{ $t('firefly.create_another') }}
</label> </label>
<label v-bind:class="{ 'text-muted': this.createAnother === false}"> <label v-bind:class="{ 'text-muted': this.createAnother === false}">
<input v-model="resetFormAfter" :disabled="this.createAnother === false" <input v-model="resetFormAfter" :disabled="this.createAnother === false"
name="reset_form" type="checkbox"> name="reset_form" type="checkbox">
Reset form after submission {{ $t('firefly.reset_after') }}
</label> </label>
</div> </div>
</div> </div>
<div class="box-footer"> <div class="box-footer">
<div class="btn-group"> <div class="btn-group">
<button class="btn btn-success" id="submitButton" @click="submit">Submit</button> <button class="btn btn-success" id="submitButton" @click="submit">{{ $t('firefly.submit') }}</button>
</div> </div>
</div> </div>
</div> </div>
@ -512,6 +515,14 @@
}).catch(error => { }).catch(error => {
console.error('Could not upload'); console.error('Could not upload');
console.error(error); console.error(error);
// console.log('Uploaded attachment #' + key);
uploads++;
if (uploads === count) {
// finally we can redirect the user onwards.
// console.log('FINAL UPLOAD');
this.redirectUser(groupId);
}
// console.log('Upload complete!');
return false; return false;
}); });
}); });
@ -557,7 +568,7 @@
this.setDefaultErrors(); this.setDefaultErrors();
this.error_message = ""; this.error_message = "";
if (errors.message.length > 0) { if (errors.message.length > 0) {
this.error_message = "There was something wrong with your submission. Please check out the errors below."; this.error_message = this.$t('firefly.errors_submission');
} else { } else {
this.error_message = ''; this.error_message = '';
} }

View File

@ -22,35 +22,35 @@
<div> <div>
<component <component
:error="error.interest_date" :error="error.interest_date"
v-model="value.interest_date" v-if="this.fields.interest_date" name="interest_date[]" title="Interest date" v-bind:is="dateComponent"></component> v-model="value.interest_date" v-if="this.fields.interest_date" name="interest_date[]" v-bind:title="$t('form.interest_date')" v-bind:is="dateComponent"></component>
<component <component
:error="error.book_date" :error="error.book_date"
v-model="value.book_date" v-if="this.fields.book_date" name="book_date[]" title="Book date" v-bind:is="dateComponent"></component> v-model="value.book_date" v-if="this.fields.book_date" name="book_date[]" v-bind:title="$t('form.book_date')" v-bind:is="dateComponent"></component>
<component <component
:error="error.process_date" :error="error.process_date"
v-model="value.process_date" v-if="this.fields.process_date" name="process_date[]" title="Process date" v-bind:is="dateComponent"></component> v-model="value.process_date" v-if="this.fields.process_date" name="process_date[]" v-bind:title="$t('form.process_date')" v-bind:is="dateComponent"></component>
<component <component
:error="error.due_date" :error="error.due_date"
v-model="value.due_date" v-if="this.fields.due_date" name="due_date[]" title="Due date" v-bind:is="dateComponent"></component> v-model="value.due_date" v-if="this.fields.due_date" name="due_date[]" v-bind:title="$t('form.due_date')" v-bind:is="dateComponent"></component>
<component <component
:error="error.payment_date" :error="error.payment_date"
v-model="value.payment_date" v-if="this.fields.payment_date" name="payment_date[]" title="Payment date" v-bind:is="dateComponent"></component> v-model="value.payment_date" v-if="this.fields.payment_date" name="payment_date[]" v-bind:title="$t('form.payment_date')" v-bind:is="dateComponent"></component>
<component <component
:error="error.invoice_date" :error="error.invoice_date"
v-model="value.invoice_date" v-if="this.fields.invoice_date" name="invoice_date[]" title="Invoice date" v-bind:is="dateComponent"></component> v-model="value.invoice_date" v-if="this.fields.invoice_date" name="invoice_date[]" v-bind:title="$t('form.invoice_date')" v-bind:is="dateComponent"></component>
<component <component
:error="error.internal_reference" :error="error.internal_reference"
v-model="value.internal_reference" v-if="this.fields.internal_reference" name="internal_reference[]" title="Internal reference" v-bind:is="stringComponent"></component> v-model="value.internal_reference" v-if="this.fields.internal_reference" name="internal_reference[]" v-bind:title="$t('form.internal_reference')" v-bind:is="stringComponent"></component>
<component <component
:error="error.attachments" :error="error.attachments"
v-model="value.attachments" v-if="this.fields.attachments" name="attachments[]" title="Attachments" v-bind:is="attachmentComponent"></component> v-model="value.attachments" v-if="this.fields.attachments" name="attachments[]" v-bind:title="$t('firefly.attachments')" v-bind:is="attachmentComponent"></component>
<component <component
:error="error.notes" :error="error.notes"
v-model="value.notes" v-if="this.fields.notes" name="notes[]" title="Notes" v-bind:is="textareaComponent"></component> v-model="value.notes" v-if="this.fields.notes" name="notes[]" v-bind:title="$t('firefly.notes')" v-bind:is="textareaComponent"></component>
</div> </div>
@ -109,7 +109,7 @@
const url = document.getElementsByTagName('base')[0].href + 'api/v1/preferences/transaction_journal_optional_fields'; const url = document.getElementsByTagName('base')[0].href + 'api/v1/preferences/transaction_journal_optional_fields';
axios.get(url).then(response => { axios.get(url).then(response => {
this.fields = response.data.data.attributes.data; this.fields = response.data.data.attributes.data;
}).catch(() => console.warn('Oh. Something went wrong')); }).catch(() => console.warn('Oh. Something went wrong loading custom transaction fields.'));
}, },
} }
} }

View File

@ -25,9 +25,9 @@
<div class="row" v-if="error_message !== ''"> <div class="row" v-if="error_message !== ''">
<div class="col-lg-12"> <div class="col-lg-12">
<div class="alert alert-danger alert-dismissible" role="alert"> <div class="alert alert-danger alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span <button type="button" class="close" data-dismiss="alert" v-bind:aria-label="$t('firefly.close')"><span
aria-hidden="true">&times;</span></button> aria-hidden="true">&times;</span></button>
<strong>Error!</strong> {{ error_message }} <strong>{{ $t("firefly.flash_error") }}</strong> {{ error_message }}
</div> </div>
</div> </div>
</div> </div>
@ -35,9 +35,9 @@
<div class="row" v-if="success_message !== ''"> <div class="row" v-if="success_message !== ''">
<div class="col-lg-12"> <div class="col-lg-12">
<div class="alert alert-success alert-dismissible" role="alert"> <div class="alert alert-success alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span <button type="button" class="close" data-dismiss="alert" v-bind:aria-label="$t('firefly.close')"><span
aria-hidden="true">&times;</span></button> aria-hidden="true">&times;</span></button>
<strong>Success!</strong> <span v-html="success_message"></span> <strong>{{ $t("firefly.flash_success") }}</strong> <span v-html="success_message"></span>
</div> </div>
</div> </div>
</div> </div>
@ -46,7 +46,7 @@
<div class="box"> <div class="box">
<div class="box-header with-border"> <div class="box-header with-border">
<h3 class="box-title"> <h3 class="box-title">
Description of the split transaction {{ $t('firefly.split_transaction_title')}}
</h3> </h3>
</div> </div>
<div class="box-body"> <div class="box-body">
@ -65,8 +65,8 @@
<div class="box"> <div class="box">
<div class="box-header with-border"> <div class="box-header with-border">
<h3 class="box-title splitTitle"> <h3 class="box-title splitTitle">
<span v-if="transactions.length > 1">Split {{ index+1 }} / {{ transactions.length }}</span> <span v-if="transactions.length > 1">{{ $t('firefly.split')}} {{ index+1 }} / {{ transactions.length }}</span>
<span v-if="transactions.length === 1">Transaction information</span> <span v-if="transactions.length === 1">{{ $t('firefly.transaction_journal_information') }}</span>
</h3> </h3>
<div class="box-tools pull-right" v-if="transactions.length > 1" x> <div class="box-tools pull-right" v-if="transactions.length > 1" x>
<button type="button" v-on:click="deleteTransaction(index, $event)" class="btn btn-xs btn-danger"><i <button type="button" v-on:click="deleteTransaction(index, $event)" class="btn btn-xs btn-danger"><i
@ -84,7 +84,7 @@
</transaction-description> </transaction-description>
<account-select <account-select
inputName="source[]" inputName="source[]"
title="Source account" v-bind:title="$t('firefly.source_account')"
:accountName="transaction.source_account.name" :accountName="transaction.source_account.name"
:accountTypeFilters="transaction.source_account.allowed_types" :accountTypeFilters="transaction.source_account.allowed_types"
:transactionType="transactionType" :transactionType="transactionType"
@ -95,7 +95,7 @@
></account-select> ></account-select>
<account-select <account-select
inputName="destination[]" inputName="destination[]"
title="Destination account" v-bind:title="$t('firefly.destination_account')"
:accountName="transaction.destination_account.name" :accountName="transaction.destination_account.name"
:accountTypeFilters="transaction.destination_account.allowed_types" :accountTypeFilters="transaction.destination_account.allowed_types"
:transactionType="transactionType" :transactionType="transactionType"
@ -134,6 +134,8 @@
v-model="transaction.foreign_amount" v-model="transaction.foreign_amount"
:transactionType="transactionType" :transactionType="transactionType"
:error="transaction.errors.foreign_amount" :error="transaction.errors.foreign_amount"
:no_currency="$t('firefly.none_in_select_list')"
v-bind:title="$t('form.foreign_amount')"
></foreign-amount> ></foreign-amount>
</div> </div>
<div class="col-lg-4"> <div class="col-lg-4">
@ -141,6 +143,7 @@
:transactionType="transactionType" :transactionType="transactionType"
v-model="transaction.budget" v-model="transaction.budget"
:error="transaction.errors.budget_id" :error="transaction.errors.budget_id"
:no_budget="$t('firefly.none_in_select_list')"
></budget> ></budget>
<category <category
:transactionType="transactionType" :transactionType="transactionType"
@ -160,7 +163,7 @@
</div> </div>
</div> </div>
<div class="box-footer" v-if="transactions.length-1 === index"> <div class="box-footer" v-if="transactions.length-1 === index">
<button class="btn btn-primary" type="button" @click="addTransaction">Add another split</button> <button class="btn btn-primary" type="button" @click="addTransaction">{{ $t('firefly.add_another_split') }}</button>
</div> </div>
</div> </div>
</div> </div>
@ -171,26 +174,26 @@
<div class="box"> <div class="box">
<div class="box-header with-border"> <div class="box-header with-border">
<h3 class="box-title"> <h3 class="box-title">
Submission {{ $t('firefly.submission') }}
</h3> </h3>
</div> </div>
<div class="box-body"> <div class="box-body">
<div class="checkbox"> <div class="checkbox">
<label> <label>
<input v-model="returnAfter" name="return_after" type="checkbox"> <input v-model="returnAfter" name="return_after" type="checkbox">
After updating, return here to continue editing. {{ $t('firefly.after_update_create_another') }}
</label> </label>
</div> </div>
<div class="checkbox"> <div class="checkbox">
<label> <label>
<input v-model="storeAsNew" name="store_as_new" type="checkbox"> <input v-model="storeAsNew" name="store_as_new" type="checkbox">
Store as a new transaction instead of updating. {{ $t('firefly.store_as_new') }}
</label> </label>
</div> </div>
</div> </div>
<div class="box-footer"> <div class="box-footer">
<div class="btn-group"> <div class="btn-group">
<button class="btn btn-success" @click="submit">Update</button> <button class="btn btn-success" @click="submit">{{ $t('firefly.update_transaction') }}</button>
</div> </div>
</div> </div>
</div> </div>
@ -733,7 +736,13 @@
// console.log('Upload complete!'); // console.log('Upload complete!');
return true; return true;
}).catch(error => { }).catch(error => {
// console.error('Could not upload'); console.error('Could not upload file.');
console.error(error);
uploads++;
this.error_message = 'Could not upload attachment: ' + error;
if (uploads === count) {
this.redirectUser(groupId);
}
// console.error(error); // console.error(error);
return false; return false;
}); });
@ -822,7 +831,7 @@
this.setDefaultErrors(); this.setDefaultErrors();
this.error_message = ""; this.error_message = "";
if (errors.message.length > 0) { if (errors.message.length > 0) {
this.error_message = "There was something wrong with your submission. Please check out the errors below."; this.error_message = this.$t('firefly.errors_submission');
} else { } else {
this.error_message = ''; this.error_message = '';
} }

View File

@ -37,7 +37,7 @@
<div class="col-sm-8"> <div class="col-sm-8">
<input type="number" @input="handleInput" ref="amount" :value="value.amount" step="any" class="form-control" <input type="number" @input="handleInput" ref="amount" :value="value.amount" step="any" class="form-control"
name="foreign_amount[]" v-if="this.enabledCurrencies.length > 0" name="foreign_amount[]" v-if="this.enabledCurrencies.length > 0"
title="Foreign amount" autocomplete="off" placeholder="Foreign amount"> :title="this.title" autocomplete="off" :placeholder="this.title">
<ul class="list-unstyled" v-for="error in this.error"> <ul class="list-unstyled" v-for="error in this.error">
<li class="text-danger">{{ error }}</li> <li class="text-danger">{{ error }}</li>
@ -49,7 +49,7 @@
<script> <script>
export default { export default {
name: "ForeignAmountSelect", name: "ForeignAmountSelect",
props: ['source', 'destination', 'transactionType', 'value','error'], props: ['source', 'destination', 'transactionType', 'value', 'error', 'no_currency', 'title'],
mounted() { mounted() {
this.loadCurrencies(); this.loadCurrencies();
}, },
@ -130,7 +130,7 @@
axios.get(URI, {}).then((res) => { axios.get(URI, {}).then((res) => {
this.currencies = [ this.currencies = [
{ {
name: '(none)', name: this.no_currency,
id: 0, id: 0,
enabled: true enabled: true
} }

View File

@ -25,15 +25,14 @@
type="text" type="text"
class="form-control" class="form-control"
name="group_title" name="group_title"
title="Description of the split transaction" v-bind:title="$t('firefly.split_transaction_title')"
ref="descr" ref="descr"
autocomplete="off" autocomplete="off"
placeholder="Description of the split transaction" v-bind:placeholder="$t('firefly.split_transaction_title')"
:value="value" @input="handleInput" :value="value" @input="handleInput"
> >
<p class="help-block" v-if="error.length === 0"> <p class="help-block" v-if="error.length === 0">
If you create a split transaction, there must be a global description for all splits {{ $t('firefly.split_transaction_title_help') }}
of the transaction.
</p> </p>
<ul class="list-unstyled" v-for="error in this.error"> <ul class="list-unstyled" v-for="error in this.error">
<li class="text-danger">{{ error }}</li> <li class="text-danger">{{ error }}</li>

View File

@ -36,7 +36,7 @@
<script> <script>
export default { export default {
name: "PiggyBank", name: "PiggyBank",
props: ['value','transactionType','error'], props: ['value','transactionType','error', 'no_piggy_bank'],
mounted() { mounted() {
this.loadPiggies(); this.loadPiggies();
}, },
@ -57,7 +57,7 @@
axios.get(URI, {}).then((res) => { axios.get(URI, {}).then((res) => {
this.piggies = [ this.piggies = [
{ {
name: '(no piggy bank)', name: this.no_piggy_bank,
id: 0, id: 0,
} }
]; ];

View File

@ -25,11 +25,11 @@
type="date" type="date"
class="form-control" class="form-control"
name="date[]" name="date[]"
title="Date" v-bind:title="$t('firefly.date')"
ref="date" ref="date"
autocomplete="off" autocomplete="off"
:disabled="index > 0" :disabled="index > 0"
placeholder="Date" v-bind:placeholder="$t('firefly.date')"
:value="value" @input="handleInput" :value="value" @input="handleInput"
> >
<ul class="list-unstyled" v-for="error in this.error"> <ul class="list-unstyled" v-for="error in this.error">

View File

@ -30,7 +30,7 @@
:autocomplete-items="autocompleteItems" :autocomplete-items="autocompleteItems"
:add-only-from-autocomplete="false" :add-only-from-autocomplete="false"
@tags-changed="update" @tags-changed="update"
placeholder="Tags" v-bind:placeholder="$t('firefly.tags')"
/> />
<ul class="list-unstyled" v-for="error in this.error"> <ul class="list-unstyled" v-for="error in this.error">
<li class="text-danger">{{ error }}</li> <li class="text-danger">{{ error }}</li>
@ -82,7 +82,7 @@
this.autocompleteItems = response.data.map(a => { this.autocompleteItems = response.data.map(a => {
return {text: a.tag}; return {text: a.tag};
}); });
}).catch(() => console.warn('Oh. Something went wrong')); }).catch(() => console.warn('Oh. Something went wrong loading tags.'));
}, 600); }, 600);
}, },
}, },

View File

@ -30,7 +30,7 @@
v-on:submit.prevent v-on:submit.prevent
ref="descr" ref="descr"
autocomplete="off" autocomplete="off"
placeholder="Description" v-bind:placeholder="$t('firefly.description')"
:value="value" @input="handleInput" :value="value" @input="handleInput"
> >
<typeahead <typeahead

View File

@ -0,0 +1,46 @@
{
"firefly": {
"welcome_back": "Co hraje?",
"flash_error": "Chyba!",
"flash_success": "\u00dasp\u011b\u0161n\u011b dokon\u010deno!",
"close": "Zav\u0159\u00edt",
"split_transaction_title": "Popis roz\u00fa\u010dtov\u00e1n\u00ed",
"errors_submission": "There was something wrong with your submission. Please check out the errors below.",
"split": "Rozd\u011blit",
"transaction_journal_information": "Informace o transakci",
"source_account": "Zdrojov\u00fd \u00fa\u010det",
"destination_account": "C\u00edlov\u00fd \u00fa\u010det",
"add_another_split": "P\u0159idat dal\u0161\u00ed roz\u00fa\u010dtov\u00e1n\u00ed",
"submission": "Submission",
"create_another": "After storing, return here to create another one.",
"reset_after": "Reset form after submission",
"submit": "Odeslat",
"amount": "\u010c\u00e1stka",
"date": "Datum",
"tags": "\u0160t\u00edtky",
"no_budget": "(\u017e\u00e1dn\u00fd rozpo\u010det)",
"category": "Kategorie",
"attachments": "P\u0159\u00edlohy",
"notes": "Pozn\u00e1mky",
"update_transaction": "Update transaction",
"after_update_create_another": "After updating, return here to continue editing.",
"store_as_new": "Store as a new transaction instead of updating.",
"split_title_help": "Pokud vytvo\u0159\u00edte roz\u00fa\u010dtov\u00e1n\u00ed, je t\u0159eba, aby zde byl celkov\u00fd popis pro v\u0161echna roz\u00fa\u010dtov\u00e1n\u00ed dan\u00e9 transakce.",
"none_in_select_list": "(\u017e\u00e1dn\u00e9)",
"no_piggy_bank": "(no piggy bank)",
"description": "Popis"
},
"form": {
"interest_date": "\u00darokov\u00e9 datum",
"book_date": "Book date",
"process_date": "Datum zpracov\u00e1n\u00ed",
"due_date": "Datum splatnosti",
"foreign_amount": "\u010c\u00e1stka v ciz\u00ed m\u011bn\u011b",
"payment_date": "Datum zaplacen\u00ed",
"invoice_date": "Datum vystaven\u00ed",
"internal_reference": "Intern\u00ed reference"
},
"config": {
"html_language": "cs"
}
}

View File

@ -0,0 +1,46 @@
{
"firefly": {
"welcome_back": "Was ist gerade los?",
"flash_error": "Fehler!",
"flash_success": "Geschafft!",
"close": "Schlie\u00dfen",
"split_transaction_title": "Beschreibung der Splittbuchung",
"errors_submission": "Problem bei der \u00dcbermittlung. Bitte \u00fcberpr\u00fcfen Sie die nachfolgenden Fehler.",
"split": "Teilen",
"transaction_journal_information": "Transaktionsinformationen",
"source_account": "Quellkonto",
"destination_account": "Zielkonto",
"add_another_split": "Eine weitere Aufteilung hinzuf\u00fcgen",
"submission": "\u00dcbermittlung",
"create_another": "Nach dem Speichern hierher zur\u00fcckkehren, um ein weiteres zu erstellen.",
"reset_after": "Formular nach der \u00dcbermittlung zur\u00fccksetzen",
"submit": "Absenden",
"amount": "Betrag",
"date": "Datum",
"tags": "Schlagw\u00f6rter",
"no_budget": "(kein Budget)",
"category": "Kategorie",
"attachments": "Anh\u00e4nge",
"notes": "Notizen",
"update_transaction": "Buchung aktualisieren",
"after_update_create_another": "Nach dem Aktualisieren hierher zur\u00fcckkehren, um weiter zu bearbeiten.",
"store_as_new": "Als neue Buchung speichern statt zu aktualisieren.",
"split_title_help": "Wenn Sie eine Splittbuchung anlegen, muss es eine eindeutige Beschreibung f\u00fcr alle Aufteilungen der Buchhaltung geben.",
"none_in_select_list": "(Keine)",
"no_piggy_bank": "(kein Sparschwein)",
"description": "Beschreibung"
},
"form": {
"interest_date": "Zinstermin",
"book_date": "Buchungsdatum",
"process_date": "Bearbeitungsdatum",
"due_date": "F\u00e4lligkeitstermin",
"foreign_amount": "Ausl\u00e4ndischer Betrag",
"payment_date": "Zahlungsdatum",
"invoice_date": "Rechnungsdatum",
"internal_reference": "Interner Verweis"
},
"config": {
"html_language": "de"
}
}

View File

@ -0,0 +1,46 @@
{
"firefly": {
"welcome_back": "\u03a4\u03b9 \u03c0\u03b1\u03af\u03b6\u03b5\u03b9;",
"flash_error": "\u03a3\u03c6\u03ac\u03bb\u03bc\u03b1!",
"flash_success": "\u0395\u03c0\u03b9\u03c4\u03c5\u03c7\u03af\u03b1!",
"close": "\u039a\u03bb\u03b5\u03af\u03c3\u03b9\u03bc\u03bf",
"split_transaction_title": "Description of the split transaction",
"errors_submission": "There was something wrong with your submission. Please check out the errors below.",
"split": "\u0394\u03b9\u03b1\u03c7\u03c9\u03c1\u03b9\u03c3\u03bc\u03cc\u03c2",
"transaction_journal_information": "Transaction information",
"source_account": "Source account",
"destination_account": "Destination account",
"add_another_split": "Add another split",
"submission": "Submission",
"create_another": "After storing, return here to create another one.",
"reset_after": "Reset form after submission",
"submit": "Submit",
"amount": "Amount",
"date": "Date",
"tags": "Tags",
"no_budget": "(no budget)",
"category": "Category",
"attachments": "\u03a3\u03c5\u03bd\u03bd\u03b7\u03bc\u03ad\u03bd\u03b1",
"notes": "Notes",
"update_transaction": "Update transaction",
"after_update_create_another": "After updating, return here to continue editing.",
"store_as_new": "Store as a new transaction instead of updating.",
"split_title_help": "If you create a split transaction, there must be a global description for all splits of the transaction.",
"none_in_select_list": "(\u03c4\u03af\u03c0\u03bf\u03c4\u03b1)",
"no_piggy_bank": "(no piggy bank)",
"description": "Description"
},
"form": {
"interest_date": "\u0397\u03bc\u03b5\u03c1\u03bf\u03bc\u03b7\u03bd\u03af\u03b1 \u03c4\u03bf\u03ba\u03b9\u03c3\u03bc\u03bf\u03cd",
"book_date": "\u0397\u03bc\u03b5\u03c1\u03bf\u03bc\u03b7\u03bd\u03af\u03b1 \u03b5\u03b3\u03b3\u03c1\u03b1\u03c6\u03ae\u03c2",
"process_date": "\u0397\u03bc\u03b5\u03c1\u03bf\u03bc\u03b7\u03bd\u03af\u03b1 \u03b5\u03c0\u03b5\u03be\u03b5\u03c1\u03b3\u03b1\u03c3\u03af\u03b1\u03c2",
"due_date": "\u0397\u03bc\u03b5\u03c1\u03bf\u03bc\u03b7\u03bd\u03af\u03b1 \u03c0\u03c1\u03bf\u03b8\u03b5\u03c3\u03bc\u03af\u03b1\u03c2",
"foreign_amount": "\u0395\u03c4\u03b5\u03c1\u03cc\u03c7\u03b8\u03c9\u03bd \u03c0\u03bf\u03c3\u03cc",
"payment_date": "\u0397\u03bc\u03b5\u03c1\u03bf\u03bc\u03b7\u03bd\u03af\u03b1 \u03c0\u03bb\u03b7\u03c1\u03c9\u03bc\u03ae\u03c2",
"invoice_date": "\u0397\u03bc\u03b5\u03c1\u03bf\u03bc\u03b7\u03bd\u03af\u03b1 \u03c4\u03b9\u03bc\u03bf\u03bb\u03cc\u03b3\u03b7\u03c3\u03b7\u03c2",
"internal_reference": "\u0395\u03c3\u03c9\u03c4\u03b5\u03c1\u03b9\u03ba\u03ae \u03b1\u03bd\u03b1\u03c6\u03bf\u03c1\u03ac"
},
"config": {
"html_language": "el"
}
}

View File

@ -0,0 +1,46 @@
{
"firefly": {
"welcome_back": "What's playing?",
"flash_error": "Error!",
"flash_success": "Success!",
"close": "Close",
"split_transaction_title": "Description of the split transaction",
"errors_submission": "There was something wrong with your submission. Please check out the errors below.",
"split": "Split",
"transaction_journal_information": "Transaction information",
"source_account": "Source account",
"destination_account": "Destination account",
"add_another_split": "Add another split",
"submission": "Submission",
"create_another": "After storing, return here to create another one.",
"reset_after": "Reset form after submission",
"submit": "Submit",
"amount": "Amount",
"date": "Date",
"tags": "Tags",
"no_budget": "(no budget)",
"category": "Category",
"attachments": "Attachments",
"notes": "Notes",
"update_transaction": "Update transaction",
"after_update_create_another": "After updating, return here to continue editing.",
"store_as_new": "Store as a new transaction instead of updating.",
"split_title_help": "If you create a split transaction, there must be a global description for all splits of the transaction.",
"none_in_select_list": "(none)",
"no_piggy_bank": "(no piggy bank)",
"description": "Description"
},
"form": {
"interest_date": "Interest date",
"book_date": "Book date",
"process_date": "Processing date",
"due_date": "Due date",
"foreign_amount": "Foreign amount",
"payment_date": "Payment date",
"invoice_date": "Invoice date",
"internal_reference": "Internal reference"
},
"config": {
"html_language": "en"
}
}

View File

@ -0,0 +1,46 @@
{
"firefly": {
"welcome_back": "\u00bfQu\u00e9 est\u00e1 pasando?",
"flash_error": "\u00a1Error!",
"flash_success": "\u00a1Operaci\u00f3n correcta!",
"close": "Cerrar",
"split_transaction_title": "Descripci\u00f3n de la transacci\u00f3n dividida",
"errors_submission": "Hubo algo malo con su env\u00edo. Por favor, revise los errores de abajo.",
"split": "Separar",
"transaction_journal_information": "Informaci\u00f3n de transacci\u00f3n",
"source_account": "Cuenta origen",
"destination_account": "Cuenta destino",
"add_another_split": "A\u00f1adir otra divisi\u00f3n",
"submission": "Env\u00edo",
"create_another": "Despu\u00e9s de guardar, vuelve aqu\u00ed para crear otro.",
"reset_after": "Restablecer formulario despu\u00e9s del env\u00edo",
"submit": "Enviar",
"amount": "Cantidad",
"date": "Fecha",
"tags": "Etiquetas",
"no_budget": "(sin presupuesto)",
"category": "Categoria",
"attachments": "Archivos adjuntos",
"notes": "Notas",
"update_transaction": "Actualizar transacci\u00f3n",
"after_update_create_another": "Despu\u00e9s de actualizar, vuelve aqu\u00ed para continuar editando.",
"store_as_new": "Almacenar como una nueva transacci\u00f3n en lugar de actualizar.",
"split_title_help": "Si crea una transacci\u00f3n dividida, debe haber una descripci\u00f3n global para todos los fragmentos de la transacci\u00f3n.",
"none_in_select_list": "(ninguno)",
"no_piggy_bank": "(sin alcanc\u00eda)",
"description": "Descripci\u00f3n"
},
"form": {
"interest_date": "Fecha de inter\u00e9s",
"book_date": "Fecha de registro",
"process_date": "Fecha de procesamiento",
"due_date": "Fecha de vencimiento",
"foreign_amount": "Cantidad extranjera",
"payment_date": "Fecha de pago",
"invoice_date": "Fecha de la factura",
"internal_reference": "Referencia interna"
},
"config": {
"html_language": "es"
}
}

View File

@ -0,0 +1,46 @@
{
"firefly": {
"welcome_back": "Que se passe-t-il ?",
"flash_error": "Erreur !",
"flash_success": "Termin\u00e9 avec succ\u00e8s !",
"close": "Fermer",
"split_transaction_title": "Description de l'op\u00e9ration ventil\u00e9e",
"errors_submission": "There was something wrong with your submission. Please check out the errors below.",
"split": "Ventiler",
"transaction_journal_information": "Informations sur les transactions",
"source_account": "Compte d'origine",
"destination_account": "Compte de destination",
"add_another_split": "Ajouter une autre fraction",
"submission": "Submission",
"create_another": "After storing, return here to create another one.",
"reset_after": "Reset form after submission",
"submit": "Soumettre",
"amount": "Montant",
"date": "Date",
"tags": "Tags",
"no_budget": "(pas de budget)",
"category": "Cat\u00e9gorie",
"attachments": "Pi\u00e8ces jointes",
"notes": "Notes",
"update_transaction": "Update transaction",
"after_update_create_another": "After updating, return here to continue editing.",
"store_as_new": "Store as a new transaction instead of updating.",
"split_title_help": "Si vous cr\u00e9ez une op\u00e9ration ventil\u00e9e, il doit y avoir une description globale pour chaque fractions de l'op\u00e9ration.",
"none_in_select_list": "(aucun)",
"no_piggy_bank": "(no piggy bank)",
"description": "Description"
},
"form": {
"interest_date": "Date de l\u2019int\u00e9r\u00eat",
"book_date": "Date de r\u00e9servation",
"process_date": "Date de traitement",
"due_date": "\u00c9ch\u00e9ance",
"foreign_amount": "Montant externe",
"payment_date": "Date de paiement",
"invoice_date": "Date de facturation",
"internal_reference": "R\u00e9f\u00e9rence interne"
},
"config": {
"html_language": "fr"
}
}

View File

@ -0,0 +1,46 @@
{
"firefly": {
"welcome_back": "Mi a helyzet?",
"flash_error": "Hiba!",
"flash_success": "Siker!",
"close": "Bez\u00e1r\u00e1s",
"split_transaction_title": "Felosztott tranzakci\u00f3 le\u00edr\u00e1sa",
"errors_submission": "There was something wrong with your submission. Please check out the errors below.",
"split": "Feloszt\u00e1s",
"transaction_journal_information": "Tranzakci\u00f3s inform\u00e1ci\u00f3k",
"source_account": "Forr\u00e1s sz\u00e1mla",
"destination_account": "C\u00e9lsz\u00e1mla",
"add_another_split": "M\u00e1sik feloszt\u00e1s hozz\u00e1ad\u00e1sa",
"submission": "Submission",
"create_another": "After storing, return here to create another one.",
"reset_after": "Reset form after submission",
"submit": "Bek\u00fcld\u00e9s",
"amount": "\u00d6sszeg",
"date": "D\u00e1tum",
"tags": "C\u00edmk\u00e9k",
"no_budget": "(nincs k\u00f6lts\u00e9gkeret)",
"category": "Kateg\u00f3ria",
"attachments": "Mell\u00e9kletek",
"notes": "Megjegyz\u00e9sek",
"update_transaction": "Update transaction",
"after_update_create_another": "After updating, return here to continue editing.",
"store_as_new": "Store as a new transaction instead of updating.",
"split_title_help": "Felosztott tranzakci\u00f3 l\u00e9trehoz\u00e1sakor meg kell adni egy glob\u00e1lis le\u00edr\u00e1st a tranzakci\u00f3 \u00f6sszes feloszt\u00e1sa r\u00e9sz\u00e9re.",
"none_in_select_list": "(nincs)",
"no_piggy_bank": "(no piggy bank)",
"description": "Le\u00edr\u00e1s"
},
"form": {
"interest_date": "Kamatfizet\u00e9si id\u0151pont",
"book_date": "K\u00f6nyvel\u00e9s d\u00e1tuma",
"process_date": "Feldolgoz\u00e1s d\u00e1tuma",
"due_date": "Lej\u00e1rati id\u0151pont",
"foreign_amount": "Foreign amount",
"payment_date": "Fizet\u00e9s d\u00e1tuma",
"invoice_date": "Sz\u00e1mla d\u00e1tuma",
"internal_reference": "Bels\u0151 hivatkoz\u00e1s"
},
"config": {
"html_language": "hu"
}
}

View File

@ -0,0 +1,46 @@
{
"firefly": {
"welcome_back": "What's playing?",
"flash_error": "Kesalahan!",
"flash_success": "Keberhasilan!",
"close": "Dekat",
"split_transaction_title": "Description of the split transaction",
"errors_submission": "There was something wrong with your submission. Please check out the errors below.",
"split": "Pisah",
"transaction_journal_information": "Informasi transaksi",
"source_account": "Source account",
"destination_account": "Destination account",
"add_another_split": "Tambahkan perpecahan lagi",
"submission": "Submission",
"create_another": "After storing, return here to create another one.",
"reset_after": "Reset form after submission",
"submit": "Menyerahkan",
"amount": "Jumlah",
"date": "Tanggal",
"tags": "Tag",
"no_budget": "(no budget)",
"category": "Kategori",
"attachments": "Lampiran",
"notes": "Notes",
"update_transaction": "Update transaction",
"after_update_create_another": "After updating, return here to continue editing.",
"store_as_new": "Store as a new transaction instead of updating.",
"split_title_help": "If you create a split transaction, there must be a global description for all splits of the transaction.",
"none_in_select_list": "(none)",
"no_piggy_bank": "(no piggy bank)",
"description": "Deskripsi"
},
"form": {
"interest_date": "Tanggal bunga",
"book_date": "Tanggal buku",
"process_date": "Tanggal pemrosesan",
"due_date": "Batas tanggal terakhir",
"foreign_amount": "Foreign amount",
"payment_date": "Tanggal pembayaran",
"invoice_date": "Tanggal faktur",
"internal_reference": "Referensi internal"
},
"config": {
"html_language": "id"
}
}

View File

@ -0,0 +1,46 @@
{
"firefly": {
"welcome_back": "La tua situazione finanziaria",
"flash_error": "Errore!",
"flash_success": "Successo!",
"close": "Chiudi",
"split_transaction_title": "Descrizione della transazione suddivisa",
"errors_submission": "Errore durante l'invio. Controlla gli errori segnalati qui sotto.",
"split": "Dividi",
"transaction_journal_information": "Informazioni transazione",
"source_account": "Conto di origine",
"destination_account": "Conto destinazione",
"add_another_split": "Aggiungi un'altra divisione",
"submission": "Invio",
"create_another": "Dopo il salvataggio, torna qui per crearne un'altra.",
"reset_after": "Resetta il modulo dopo l'invio",
"submit": "Invia",
"amount": "Conto",
"date": "Data",
"tags": "Etichette",
"no_budget": "(nessun budget)",
"category": "Categoria",
"attachments": "Allegati",
"notes": "Note",
"update_transaction": "Aggiorna transazione",
"after_update_create_another": "Dopo l'aggiornamento, torna qui per continuare la modifica.",
"store_as_new": "Salva come nuova transazione invece di aggiornarla.",
"split_title_help": "Se crei una transazione suddivisa \u00e8 necessario che ci sia una descrizione globale per tutte le suddivisioni della transazione.",
"none_in_select_list": "(nessuna)",
"no_piggy_bank": "(nessun salvadanaio)",
"description": "Descrizione"
},
"form": {
"interest_date": "Data interesse",
"book_date": "Data contabile",
"process_date": "Data elaborazione",
"due_date": "Data scadenza",
"foreign_amount": "Importo estero",
"payment_date": "Data pagamento",
"invoice_date": "Data fatturazione",
"internal_reference": "Riferimento interno"
},
"config": {
"html_language": "it"
}
}

View File

@ -0,0 +1,46 @@
{
"firefly": {
"welcome_back": "Hvordan g\u00e5r det?",
"flash_error": "Feil!",
"flash_success": "Suksess!",
"close": "Lukk",
"split_transaction_title": "Description of the split transaction",
"errors_submission": "There was something wrong with your submission. Please check out the errors below.",
"split": "Del opp",
"transaction_journal_information": "Transaksjonsinformasjon",
"source_account": "Source account",
"destination_account": "Destination account",
"add_another_split": "Legg til en oppdeling til",
"submission": "Submission",
"create_another": "After storing, return here to create another one.",
"reset_after": "Reset form after submission",
"submit": "Send inn",
"amount": "Bel\u00f8p",
"date": "Dato",
"tags": "Tagger",
"no_budget": "(ingen budsjett)",
"category": "Kategori",
"attachments": "Vedlegg",
"notes": "Notater",
"update_transaction": "Update transaction",
"after_update_create_another": "After updating, return here to continue editing.",
"store_as_new": "Store as a new transaction instead of updating.",
"split_title_help": "If you create a split transaction, there must be a global description for all splits of the transaction.",
"none_in_select_list": "(ingen)",
"no_piggy_bank": "(no piggy bank)",
"description": "Beskrivelse"
},
"form": {
"interest_date": "Rentedato",
"book_date": "Bokf\u00f8ringsdato",
"process_date": "Prosesseringsdato",
"due_date": "Forfallsdato",
"foreign_amount": "Utenlandske bel\u00f8p",
"payment_date": "Betalingsdato",
"invoice_date": "Fakturadato",
"internal_reference": "Intern referanse"
},
"config": {
"html_language": "nb"
}
}

View File

@ -0,0 +1,46 @@
{
"firefly": {
"welcome_back": "Hoe staat het er voor?",
"flash_error": "Fout!",
"flash_success": "Gelukt!",
"close": "Sluiten",
"split_transaction_title": "Beschrijving van de gesplitste transactie",
"errors_submission": "Er ging iets mis. Check de errors.",
"split": "Splitsen",
"transaction_journal_information": "Transactieinformatie",
"source_account": "Bronrekening",
"destination_account": "Doelrekening",
"add_another_split": "Voeg een split toe",
"submission": "Indienen",
"create_another": "Terug naar deze pagina voor een nieuwe transactie.",
"reset_after": "Reset formulier na opslaan",
"submit": "Invoeren",
"amount": "Bedrag",
"date": "Datum",
"tags": "Tags",
"no_budget": "(geen budget)",
"category": "Categorie",
"attachments": "Bijlagen",
"notes": "Notities",
"update_transaction": "Update transactie",
"after_update_create_another": "Na het opslaan terug om door te gaan met wijzigen.",
"store_as_new": "Opslaan als nieuwe transactie ipv de huidige bij te werken.",
"split_title_help": "Als je een gesplitste transactie maakt, moet er een algemene beschrijving zijn voor alle splitsingen van de transactie.",
"none_in_select_list": "(geen)",
"no_piggy_bank": "(geen spaarpotje)",
"description": "Omschrijving"
},
"form": {
"interest_date": "Rentedatum",
"book_date": "Boekdatum",
"process_date": "Verwerkingsdatum",
"due_date": "Vervaldatum",
"foreign_amount": "Bedrag in vreemde valuta",
"payment_date": "Betalingsdatum",
"invoice_date": "Factuurdatum",
"internal_reference": "Interne verwijzing"
},
"config": {
"html_language": "nl"
}
}

View File

@ -0,0 +1,32 @@
{
"firefly": {
"welcome_back": "Hvordan g\u00e5r det?",
"flash_error": "Feil!",
"flash_success": "Suksess!",
"close": "Lukk",
"split_transaction_title": "Description of the split transaction",
"split": "Del opp",
"transaction_journal_information": "Transaksjonsinformasjon",
"source_account": "Source account",
"destination_account": "Destination account",
"add_another_split": "Legg til en oppdeling til",
"submit": "Send inn",
"amount": "Bel\u00f8p",
"no_budget": "(ingen budsjett)",
"category": "Kategori",
"attachments": "Vedlegg",
"notes": "Notater"
},
"form": {
"interest_date": "Rentedato",
"book_date": "Bokf\u00f8ringsdato",
"process_date": "Prosesseringsdato",
"due_date": "Forfallsdato",
"payment_date": "Betalingsdato",
"invoice_date": "Fakturadato",
"internal_reference": "Intern referanse"
},
"config": {
"html_language": "no"
}
}

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