diff --git a/.deploy/docker/.env.docker b/.deploy/docker/.env.docker index a891333746..3da4a48d0a 100644 --- a/.deploy/docker/.env.docker +++ b/.deploy/docker/.env.docker @@ -45,6 +45,14 @@ DB_DATABASE=${FF_DB_NAME} DB_USERNAME=${FF_DB_USER} DB_PASSWORD="${FF_DB_PASSWORD}" +# PostgreSQL supports SSL. You can configure it here. +PGSQL_SSL=${PGSQL_SSL} +PGSQL_SSL_MODE=${PGSQL_SSL_MODE} +PGSQL_SSL_ROOT_CERT=${PGSQL_SSL_ROOT_CERT} +PGSQL_SSL_CERT=${PGSQL_SSL_CERT} +PGSQL_SSL_KEY=${PGSQL_SSL_KEY} +PGSQL_SSL_CRL_FILE=${PGSQL_SSL_CRL_FILE} + # If you're looking for performance improvements, you could install memcached. CACHE_DRIVER=file SESSION_DRIVER=file diff --git a/.deploy/heroku/.env.heroku b/.deploy/heroku/.env.heroku index e56088cd5e..804b7f6fc1 100644 --- a/.deploy/heroku/.env.heroku +++ b/.deploy/heroku/.env.heroku @@ -42,7 +42,12 @@ DB_CONNECTION=pgsql - +# PostgreSQL supports SSL. You can configure it here. +PGSQL_SSL_MODE=prefer +PGSQL_SSL_ROOT_CERT=null +PGSQL_SSL_CERT=null +PGSQL_SSL_KEY=null +PGSQL_SSL_CRL_FILE=null # If you're looking for performance improvements, you could install memcached. diff --git a/.env.example b/.env.example index 4af78b90fd..a5899ff9d7 100644 --- a/.env.example +++ b/.env.example @@ -45,6 +45,13 @@ DB_DATABASE=homestead DB_USERNAME=homestead DB_PASSWORD=secret +# PostgreSQL supports SSL. You can configure it here. +PGSQL_SSL_MODE=prefer +PGSQL_SSL_ROOT_CERT=null +PGSQL_SSL_CERT=null +PGSQL_SSL_KEY=null +PGSQL_SSL_CRL_FILE=null + # If you're looking for performance improvements, you could install memcached. CACHE_DRIVER=file SESSION_DRIVER=file diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 3d0e8ff063..f152c20230 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,8 +1,10 @@ Fixes issue # (if relevant) diff --git a/.sandstorm/changelog.md b/.sandstorm/changelog.md index 2740887540..a77ee7e7c8 100644 --- a/.sandstorm/changelog.md +++ b/.sandstorm/changelog.md @@ -1,3 +1,12 @@ +# 4.7.15 (API 0.9.2) +- 4.7.15 was released to fix some issues upgrading from older versions. +- [Issue 2128](https://github.com/firefly-iii/firefly-iii/issues/2128) Support for Postgres SSL +- [Issue 2120](https://github.com/firefly-iii/firefly-iii/issues/2120) Add a missing meta tag, thanks to @lastlink +- Search is a lot faster now. +- [Issue 2125](https://github.com/firefly-iii/firefly-iii/issues/2125) Decryption issues during upgrade +- [Issue 2130](https://github.com/firefly-iii/firefly-iii/issues/2130) Fixed database migrations and rollbacks. +- [Issue 2135](https://github.com/firefly-iii/firefly-iii/issues/2135) Date fixes in transaction overview + # 4.7.14 (API 0.9.2) - 4.7.14 was released to fix an issue with the Composer installation script. diff --git a/.sandstorm/sandstorm-pkgdef.capnp b/.sandstorm/sandstorm-pkgdef.capnp index 7b50c9fd7e..7a4ea89516 100644 --- a/.sandstorm/sandstorm-pkgdef.capnp +++ b/.sandstorm/sandstorm-pkgdef.capnp @@ -15,8 +15,8 @@ const pkgdef :Spk.PackageDefinition = ( manifest = ( appTitle = (defaultText = "Firefly III"), - appVersion = 24, - appMarketingVersion = (defaultText = "4.7.14"), + appVersion = 25, + appMarketingVersion = (defaultText = "4.7.15"), actions = [ # Define your "new document" handlers here. diff --git a/app/Console/Commands/UpgradeDatabase.php b/app/Console/Commands/UpgradeDatabase.php index 9a5cbeaf37..8b5ef9267e 100644 --- a/app/Console/Commands/UpgradeDatabase.php +++ b/app/Console/Commands/UpgradeDatabase.php @@ -28,6 +28,7 @@ declare(strict_types=1); namespace FireflyIII\Console\Commands; +use Crypt; use DB; use Exception; use FireflyIII\Models\Account; @@ -53,6 +54,7 @@ use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; use FireflyIII\Repositories\Journal\JournalRepositoryInterface; use FireflyIII\User; use Illuminate\Console\Command; +use Illuminate\Contracts\Encryption\DecryptException; use Illuminate\Database\QueryException; use Illuminate\Support\Collection; use Log; @@ -106,6 +108,22 @@ class UpgradeDatabase extends Command return 0; } + /** + * @param string $value + * + * @return string + */ + private function tryDecrypt(string $value): string + { + try { + $value = Crypt::decrypt($value); + } catch (DecryptException $e) { + Log::debug(sprintf('Could not decrypt. %s', $e->getMessage())); + } + + return $value; + } + /** * Since it is one routine these warnings make sense and should be supressed. * @@ -127,8 +145,14 @@ class UpgradeDatabase extends Command return; } + $currencyCode = $this->tryDecrypt($currencyPreference->data); - $currency = TransactionCurrency::where('code', $currencyPreference->data)->first(); + // try json decrypt just in case. + if (\strlen($currencyCode) > 3) { + $currencyCode = json_decode($currencyCode) ?? 'EUR'; + } + + $currency = TransactionCurrency::where('code', $currencyCode)->first(); if (null === $currency) { $this->line('Fall back to default currency in migrateBillsToRules().'); $currency = app('amount')->getDefaultCurrencyByUser($user); diff --git a/app/Helpers/Collector/TransactionCollector.php b/app/Helpers/Collector/TransactionCollector.php index e46b63fb4f..eabf55e30f 100644 --- a/app/Helpers/Collector/TransactionCollector.php +++ b/app/Helpers/Collector/TransactionCollector.php @@ -651,6 +651,40 @@ class TransactionCollector implements TransactionCollectorInterface return $this; } + /** + * Search for words in descriptions. + * + * @param array $array + * + * @return TransactionCollectorInterface + */ + public function setSearchWords(array $array): TransactionCollectorInterface + { + // 'transaction_journals.description', + $this->query->where( + function (EloquentBuilder $q) use ($array) { + $q->where( + function (EloquentBuilder $q1) use ($array) { + foreach ($array as $word) { + $keyword = sprintf('%%%s%%', $word); + $q1->where('transaction_journals.description', 'LIKE', $keyword); + } + } + ); + $q->orWhere( + function (EloquentBuilder $q2) use ($array) { + foreach ($array as $word) { + $keyword = sprintf('%%%s%%', $word); + $q2->where('transactions.description', 'LIKE', $keyword); + } + } + ); + } + ); + + return $this; + } + /** * @param Tag $tag * diff --git a/app/Helpers/Collector/TransactionCollectorInterface.php b/app/Helpers/Collector/TransactionCollectorInterface.php index b1bd615c68..f5309cff16 100644 --- a/app/Helpers/Collector/TransactionCollectorInterface.php +++ b/app/Helpers/Collector/TransactionCollectorInterface.php @@ -272,6 +272,15 @@ interface TransactionCollectorInterface */ public function setRange(Carbon $start, Carbon $end): TransactionCollectorInterface; + /** + * Search for words in descriptions. + * + * @param array $array + * + * @return TransactionCollectorInterface + */ + public function setSearchWords(array $array): TransactionCollectorInterface; + /** * Set the tag to collect from. * diff --git a/app/Http/Controllers/SearchController.php b/app/Http/Controllers/SearchController.php index 1ab40fe1ac..b186248d12 100644 --- a/app/Http/Controllers/SearchController.php +++ b/app/Http/Controllers/SearchController.php @@ -67,9 +67,10 @@ class SearchController extends Controller // parse search terms: $searcher->parseQuery($fullQuery); $query = $searcher->getWordsAsString(); + $modifiers = $searcher->getModifiers(); $subTitle = (string)trans('breadcrumbs.search_result', ['query' => $query]); - return view('search.index', compact('query', 'fullQuery', 'subTitle')); + return view('search.index', compact('query','modifiers', 'fullQuery', 'subTitle')); } /** @@ -83,25 +84,14 @@ class SearchController extends Controller public function search(Request $request, SearchInterface $searcher): JsonResponse { $fullQuery = (string)$request->get('query'); - $transactions = new Collection; - // cache - $cache = new CacheProperties; - $cache->addProperty('search'); - $cache->addProperty($fullQuery); - if ($cache->has()) { - $transactions = $cache->get(); // @codeCoverageIgnore - } + $searcher->parseQuery($fullQuery); + $searcher->setLimit((int)config('firefly.search_result_limit')); + $transactions = $searcher->searchTransactions(); + $searchTime = $searcher->searchTime(); // in seconds - if (!$cache->has()) { - // parse search terms: - $searcher->parseQuery($fullQuery); - $searcher->setLimit((int)config('firefly.search_result_limit')); - $transactions = $searcher->searchTransactions(); - $cache->store($transactions); - } try { - $html = view('search.search', compact('transactions'))->render(); + $html = view('search.search', compact('transactions','searchTime'))->render(); // @codeCoverageIgnoreStart } catch (Throwable $e) { Log::error(sprintf('Cannot render search.search: %s', $e->getMessage())); diff --git a/app/Repositories/Account/AccountRepository.php b/app/Repositories/Account/AccountRepository.php index ea233c95c8..89848b5fe0 100644 --- a/app/Repositories/Account/AccountRepository.php +++ b/app/Repositories/Account/AccountRepository.php @@ -556,6 +556,25 @@ class AccountRepository implements AccountRepositoryInterface return $result; } + /** + * @param string $query + * @param array $types + * + * @return Collection + */ + public function searchAccount(string $query, array $types): Collection + { + $dbQuery = $this->user->accounts(); + $search = sprintf('%%%s%%', $query); + if (\count($types) > 0) { + $dbQuery->leftJoin('account_types', 'accounts.account_type_id', '=', 'account_types.id'); + $dbQuery->whereIn('account_types.type', $types); + } + $dbQuery->where('name', 'LIKE', $search); + + return $dbQuery->get(['accounts.*']); + } + /** * @param User $user */ diff --git a/app/Repositories/Account/AccountRepositoryInterface.php b/app/Repositories/Account/AccountRepositoryInterface.php index 00722f91ec..7d0382ca10 100644 --- a/app/Repositories/Account/AccountRepositoryInterface.php +++ b/app/Repositories/Account/AccountRepositoryInterface.php @@ -36,6 +36,7 @@ use Illuminate\Support\Collection; */ interface AccountRepositoryInterface { + /** * Moved here from account CRUD. * @@ -247,6 +248,14 @@ interface AccountRepositoryInterface */ public function oldestJournalDate(Account $account): ?Carbon; + /** + * @param string $query + * @param array $types + * + * @return Collection + */ + public function searchAccount(string $query, array $types): Collection; + /** * @param User $user */ diff --git a/app/Repositories/Bill/BillRepository.php b/app/Repositories/Bill/BillRepository.php index 5b2d78cf74..f7888eb4ce 100644 --- a/app/Repositories/Bill/BillRepository.php +++ b/app/Repositories/Bill/BillRepository.php @@ -623,6 +623,18 @@ class BillRepository implements BillRepositoryInterface return $start; } + /** + * @param string $query + * + * @return Collection + */ + public function searchBill(string $query): Collection + { + $query = sprintf('%%%s%%', $query); + + return $this->user->bills()->where('name', 'LIKE', $query)->get(); + } + /** * @param User $user */ diff --git a/app/Repositories/Bill/BillRepositoryInterface.php b/app/Repositories/Bill/BillRepositoryInterface.php index 2046fe4c90..e90abc44e8 100644 --- a/app/Repositories/Bill/BillRepositoryInterface.php +++ b/app/Repositories/Bill/BillRepositoryInterface.php @@ -33,7 +33,6 @@ use Illuminate\Support\Collection; */ interface BillRepositoryInterface { - /** * @param Bill $bill * @@ -236,6 +235,13 @@ interface BillRepositoryInterface */ public function nextExpectedMatch(Bill $bill, Carbon $date): Carbon; + /** + * @param string $query + * + * @return Collection + */ + public function searchBill(string $query): Collection; + /** * @param User $user */ diff --git a/app/Repositories/Budget/BudgetRepository.php b/app/Repositories/Budget/BudgetRepository.php index 0b61d860d9..e079b4edaa 100644 --- a/app/Repositories/Budget/BudgetRepository.php +++ b/app/Repositories/Budget/BudgetRepository.php @@ -635,6 +635,20 @@ class BudgetRepository implements BudgetRepositoryInterface return $result; } + /** + * @param string $query + * + * @return Collection + */ + public function searchBudget(string $query): Collection + { + $query = sprintf('%%%s%%', $query); + + return $this->user->budgets()->where('name', 'LIKE', $query)->get(); + } + + /** @noinspection MoreThanThreeArgumentsInspection */ + /** * @param TransactionCurrency $currency * @param Carbon $start @@ -662,8 +676,6 @@ class BudgetRepository implements BudgetRepositoryInterface return $availableBudget; } - /** @noinspection MoreThanThreeArgumentsInspection */ - /** * @param Budget $budget * @param int $order @@ -903,6 +915,8 @@ class BudgetRepository implements BudgetRepositoryInterface return $limit; } + /** @noinspection MoreThanThreeArgumentsInspection */ + /** * @param Budget $budget * @param array $data @@ -922,8 +936,6 @@ class BudgetRepository implements BudgetRepositoryInterface return $budget; } - /** @noinspection MoreThanThreeArgumentsInspection */ - /** * @param AvailableBudget $availableBudget * @param array $data diff --git a/app/Repositories/Budget/BudgetRepositoryInterface.php b/app/Repositories/Budget/BudgetRepositoryInterface.php index 3100064f8f..d61c5ed5ee 100644 --- a/app/Repositories/Budget/BudgetRepositoryInterface.php +++ b/app/Repositories/Budget/BudgetRepositoryInterface.php @@ -169,8 +169,6 @@ interface BudgetRepositoryInterface */ public function getBudgets(): Collection; - /** @noinspection MoreThanThreeArgumentsInspection */ - /** * Get all budgets with these ID's. * @@ -180,6 +178,8 @@ interface BudgetRepositoryInterface */ public function getByIds(array $budgetIds): Collection; + /** @noinspection MoreThanThreeArgumentsInspection */ + /** * @return Collection */ @@ -194,6 +194,13 @@ interface BudgetRepositoryInterface */ public function getNoBudgetPeriodReport(Collection $accounts, Carbon $start, Carbon $end): array; + /** + * @param string $query + * + * @return Collection + */ + public function searchBudget(string $query): Collection; + /** * @param TransactionCurrency $currency * @param Carbon $start diff --git a/app/Repositories/Category/CategoryRepository.php b/app/Repositories/Category/CategoryRepository.php index 4d09089b51..24f695623b 100644 --- a/app/Repositories/Category/CategoryRepository.php +++ b/app/Repositories/Category/CategoryRepository.php @@ -531,6 +531,18 @@ class CategoryRepository implements CategoryRepositoryInterface /** @noinspection MoreThanThreeArgumentsInspection */ + /** + * @param string $query + * + * @return Collection + */ + public function searchCategory(string $query): Collection + { + $query = sprintf('%%%s%%', $query); + + return $this->user->categories()->where('name', 'LIKE', $query)->get(); + } + /** * @param User $user */ diff --git a/app/Repositories/Category/CategoryRepositoryInterface.php b/app/Repositories/Category/CategoryRepositoryInterface.php index 65f0c79b85..edd4a33597 100644 --- a/app/Repositories/Category/CategoryRepositoryInterface.php +++ b/app/Repositories/Category/CategoryRepositoryInterface.php @@ -40,7 +40,6 @@ interface CategoryRepositoryInterface */ public function destroy(Category $category): bool; - /** @noinspection MoreThanThreeArgumentsInspection */ /** * @param Collection $categories * @param Collection $accounts @@ -52,6 +51,7 @@ interface CategoryRepositoryInterface public function earnedInPeriod(Collection $categories, Collection $accounts, Carbon $start, Carbon $end): string; /** @noinspection MoreThanThreeArgumentsInspection */ + /** * @param Collection $categories * @param Collection $accounts @@ -62,6 +62,8 @@ interface CategoryRepositoryInterface */ public function earnedInPeriodCollection(Collection $categories, Collection $accounts, Carbon $start, Carbon $end): Collection; + /** @noinspection MoreThanThreeArgumentsInspection */ + /** * A very cryptic method name that means: * @@ -119,8 +121,6 @@ interface CategoryRepositoryInterface */ public function getByIds(array $categoryIds): Collection; - /** @noinspection MoreThanThreeArgumentsInspection */ - /** * Returns a list of all the categories belonging to a user. * @@ -128,6 +128,8 @@ interface CategoryRepositoryInterface */ public function getCategories(): Collection; + /** @noinspection MoreThanThreeArgumentsInspection */ + /** * Return most recent transaction(journal) date or null when never used before. * @@ -138,8 +140,6 @@ interface CategoryRepositoryInterface */ public function lastUseDate(Category $category, Collection $accounts): ?Carbon; - /** @noinspection MoreThanThreeArgumentsInspection */ - /** * @param Collection $categories * @param Collection $accounts @@ -150,6 +150,8 @@ interface CategoryRepositoryInterface */ public function periodExpenses(Collection $categories, Collection $accounts, Carbon $start, Carbon $end): array; + /** @noinspection MoreThanThreeArgumentsInspection */ + /** * @param Collection $accounts * @param Carbon $start @@ -169,8 +171,6 @@ interface CategoryRepositoryInterface */ public function periodIncome(Collection $categories, Collection $accounts, Carbon $start, Carbon $end): array; - /** @noinspection MoreThanThreeArgumentsInspection */ - /** * @param Collection $accounts * @param Carbon $start @@ -182,6 +182,15 @@ interface CategoryRepositoryInterface /** @noinspection MoreThanThreeArgumentsInspection */ + /** + * @param string $query + * + * @return Collection + */ + public function searchCategory(string $query): Collection; + + /** @noinspection MoreThanThreeArgumentsInspection */ + /** * @param User $user */ diff --git a/app/Support/Amount.php b/app/Support/Amount.php index bfa19e8bc2..9f9789aa14 100644 --- a/app/Support/Amount.php +++ b/app/Support/Amount.php @@ -22,10 +22,13 @@ declare(strict_types=1); namespace FireflyIII\Support; +use Crypt; use FireflyIII\Exceptions\FireflyException; use FireflyIII\Models\TransactionCurrency; use FireflyIII\User; +use Illuminate\Contracts\Encryption\DecryptException; use Illuminate\Support\Collection; +use Log; use Preferences as Prefs; /** @@ -237,9 +240,18 @@ class Amount return $cache->get(); // @codeCoverageIgnore } $currencyPreference = Prefs::getForUser($user, 'currencyPreference', config('firefly.default_currency', 'EUR')); - $currency = TransactionCurrency::where('code', $currencyPreference->data)->first(); + + // at this point the currency preference could be encrypted, if coming from an old version. + $currencyCode = $this->tryDecrypt((string)$currencyPreference->data); + + // could still be json encoded: + if (\strlen($currencyCode) > 3) { + $currencyCode = json_decode($currencyCode) ?? 'EUR'; + } + + $currency = TransactionCurrency::where('code', $currencyCode)->first(); if (null === $currency) { - throw new FireflyException(sprintf('No currency found with code "%s"', $currencyPreference->data)); + throw new FireflyException(sprintf('No currency found with code "%s"', $currencyCode)); } $cache->store($currency); @@ -265,4 +277,20 @@ class Amount 'zero' => $positive, ]; } + + /** + * @param string $value + * + * @return string + */ + private function tryDecrypt(string $value): string + { + try { + $value = Crypt::decrypt($value); + } catch (DecryptException $e) { + Log::debug(sprintf('Could not decrypt. %s', $e->getMessage())); + } + + return $value; + } } diff --git a/app/Support/Import/JobConfiguration/Ynab/SelectBudgetHandler.php b/app/Support/Import/JobConfiguration/Ynab/SelectBudgetHandler.php index 1c3ddbe546..4a3ebadba7 100644 --- a/app/Support/Import/JobConfiguration/Ynab/SelectBudgetHandler.php +++ b/app/Support/Import/JobConfiguration/Ynab/SelectBudgetHandler.php @@ -164,7 +164,7 @@ class SelectBudgetHandler implements YnabJobConfigurationInterface { $currency = $this->currencyRepository->findByCodeNull($code); if (null === $currency) { - Log::debug(sprintf('No currency found with code "%s"', $code)); + Log::debug(sprintf('No currency X found with code "%s"', $code)); return false; } diff --git a/app/Support/Import/Routine/Ynab/ImportDataHandler.php b/app/Support/Import/Routine/Ynab/ImportDataHandler.php index c572118da8..1468b0e356 100644 --- a/app/Support/Import/Routine/Ynab/ImportDataHandler.php +++ b/app/Support/Import/Routine/Ynab/ImportDataHandler.php @@ -145,7 +145,7 @@ class ImportDataHandler } $destinationData = [ - 'name' => $transaction['payee_name'], + 'name' => str_replace('Transfer: ', '', $transaction['payee_name']), 'iban' => null, 'number' => $transaction['payee_id'], 'bic' => null, diff --git a/app/Support/Navigation.php b/app/Support/Navigation.php index 0b7b4262ad..850739d3de 100644 --- a/app/Support/Navigation.php +++ b/app/Support/Navigation.php @@ -47,12 +47,23 @@ class Navigation $add = ($skip + 1); $functionMap = [ - '1D' => 'addDays', 'daily' => 'addDays', - '1W' => 'addWeeks', 'weekly' => 'addWeeks', 'week' => 'addWeeks', - '1M' => 'addMonths', 'month' => 'addMonths', 'monthly' => 'addMonths', '3M' => 'addMonths', - 'quarter' => 'addMonths', 'quarterly' => 'addMonths', '6M' => 'addMonths', 'half-year' => 'addMonths', - 'year' => 'addYears', 'yearly' => 'addYears', '1Y' => 'addYears', - 'custom' => 'addMonths', // custom? just add one month. + '1D' => 'addDays', + 'daily' => 'addDays', + '1W' => 'addWeeks', + 'weekly' => 'addWeeks', + 'week' => 'addWeeks', + '1M' => 'addMonths', + 'month' => 'addMonths', + 'monthly' => 'addMonths', + '3M' => 'addMonths', + 'quarter' => 'addMonths', + 'quarterly' => 'addMonths', + '6M' => 'addMonths', + 'half-year' => 'addMonths', + 'year' => 'addYears', + 'yearly' => 'addYears', + '1Y' => 'addYears', + 'custom' => 'addMonths', // custom? just add one month. ]; $modifierMap = [ 'quarter' => 3, @@ -71,11 +82,16 @@ class Navigation $function = $functionMap[$repeatFreq]; $date->$function($add); - // if period is 1M and diff in month is 2 and new DOM = 1, sub a day: + // if period is 1M and diff in month is 2 and new DOM > 1, sub a number of days: + // result is: + // '2019-01-29', '2019-02-28' + // '2019-01-30', '2019-02-28' + // '2019-01-31', '2019-02-28' + $months = ['1M', 'month', 'monthly']; $difference = $date->month - $theDate->month; - if (2 === $difference && 1 === $date->day && \in_array($repeatFreq, $months, true)) { - $date->subDay(); + if (2 === $difference && $date->day > 0 && \in_array($repeatFreq, $months, true)) { + $date->subDays($date->day); } return $date; @@ -135,7 +151,7 @@ class Navigation // per year while ($perYearEnd >= $perYearStart) { $perYearEnd = $this->startOfPeriod($perYearEnd, '1Y'); - $currentEnd = $this->endOfPeriod($perYearEnd, '1Y')->subDay()->endOfDay(); + $currentEnd = $this->endOfPeriod($perYearEnd, '1Y')->endOfDay(); if ($currentEnd->gt($start)) { $periods[] = [ 'start' => $perYearEnd, @@ -162,11 +178,22 @@ class Navigation $currentEnd = clone $end; $functionMap = [ - '1D' => 'endOfDay', 'daily' => 'endOfDay', - '1W' => 'addWeek', 'week' => 'addWeek', 'weekly' => 'addWeek', - '1M' => 'addMonth', 'month' => 'addMonth', 'monthly' => 'addMonth', - '3M' => 'addMonths', 'quarter' => 'addMonths', 'quarterly' => 'addMonths', '6M' => 'addMonths', 'half-year' => 'addMonths', - 'year' => 'addYear', 'yearly' => 'addYear', '1Y' => 'addYear', + '1D' => 'endOfDay', + 'daily' => 'endOfDay', + '1W' => 'addWeek', + 'week' => 'addWeek', + 'weekly' => 'addWeek', + '1M' => 'addMonth', + 'month' => 'addMonth', + 'monthly' => 'addMonth', + '3M' => 'addMonths', + 'quarter' => 'addMonths', + 'quarterly' => 'addMonths', + '6M' => 'addMonths', + 'half-year' => 'addMonths', + 'year' => 'addYear', + 'yearly' => 'addYear', + '1Y' => 'addYear', ]; $modifierMap = [ 'quarter' => 3, @@ -200,14 +227,15 @@ class Navigation if (isset($modifierMap[$repeatFreq])) { $currentEnd->$function($modifierMap[$repeatFreq]); - if (\in_array($repeatFreq, $subDay, true)) { $currentEnd->subDay(); } + $currentEnd->endOfDay(); return $currentEnd; } $currentEnd->$function(); + $currentEnd->endOfDay(); if (\in_array($repeatFreq, $subDay, true)) { $currentEnd->subDay(); } diff --git a/app/Support/Search/Search.php b/app/Support/Search/Search.php index 43477c3180..b0c8ed1909 100644 --- a/app/Support/Search/Search.php +++ b/app/Support/Search/Search.php @@ -24,9 +24,15 @@ namespace FireflyIII\Support\Search; use Carbon\Carbon; use FireflyIII\Helpers\Collector\TransactionCollectorInterface; +use FireflyIII\Helpers\Filter\DoubleTransactionFilter; use FireflyIII\Helpers\Filter\InternalTransferFilter; -use FireflyIII\Models\Transaction; +use FireflyIII\Models\AccountType; +use FireflyIII\Repositories\Account\AccountRepositoryInterface; +use FireflyIII\Repositories\Bill\BillRepositoryInterface; +use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; +use FireflyIII\Repositories\Category\CategoryRepositoryInterface; use FireflyIII\User; +use Illuminate\Pagination\LengthAwarePaginator; use Illuminate\Support\Collection; use Log; @@ -35,12 +41,22 @@ use Log; */ class Search implements SearchInterface { + /** @var AccountRepositoryInterface */ + private $accountRepository; + /** @var BillRepositoryInterface */ + private $billRepository; + /** @var BudgetRepositoryInterface */ + private $budgetRepository; + /** @var CategoryRepositoryInterface */ + private $categoryRepository; /** @var int */ private $limit = 100; /** @var Collection */ private $modifiers; /** @var string */ private $originalQuery = ''; + /** @var float */ + private $startTime; /** @var User */ private $user; /** @var array */ @@ -53,13 +69,25 @@ class Search implements SearchInterface */ public function __construct() { - $this->modifiers = new Collection; - $this->validModifiers = (array)config('firefly.search_modifiers'); + $this->modifiers = new Collection; + $this->validModifiers = (array)config('firefly.search_modifiers'); + $this->startTime = microtime(true); + $this->accountRepository = app(AccountRepositoryInterface::class); + $this->categoryRepository = app(CategoryRepositoryInterface::class); + $this->budgetRepository = app(BudgetRepositoryInterface::class); + $this->billRepository = app(BillRepositoryInterface::class); if ('testing' === config('app.env')) { Log::warning(sprintf('%s should not be instantiated in the TEST environment!', \get_class($this))); } + } + /** + * @return Collection + */ + public function getModifiers(): Collection + { + return $this->modifiers; } /** @@ -99,78 +127,44 @@ class Search implements SearchInterface $filteredQuery = str_replace($match, '', $filteredQuery); } $filteredQuery = trim(str_replace(['"', "'"], '', $filteredQuery)); - if ('' != $filteredQuery) { + if ('' !== $filteredQuery) { $this->words = array_map('trim', explode(' ', $filteredQuery)); } } /** - * @return Collection + * @return float */ - public function searchTransactions(): Collection + public function searchTime(): float + { + return microtime(true) - $this->startTime; + } + + /** + * @return LengthAwarePaginator + */ + public function searchTransactions(): LengthAwarePaginator { Log::debug('Start of searchTransactions()'); - $pageSize = 100; - $processed = 0; - $page = 1; - $result = new Collection(); - $startTime = microtime(true); - do { - /** @var TransactionCollectorInterface $collector */ - $collector = app(TransactionCollectorInterface::class); - $collector->setAllAssetAccounts()->setLimit($pageSize)->setPage($page)->withOpposingAccount(); - if ($this->hasModifiers()) { - $collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation(); - } + $pageSize = 50; + $page = 1; - // some modifiers can be applied to the collector directly. - $collector = $this->applyModifiers($collector); + /** @var TransactionCollectorInterface $collector */ + $collector = app(TransactionCollectorInterface::class); + $collector->setAllAssetAccounts()->setLimit($pageSize)->setPage($page)->withOpposingAccount(); + if ($this->hasModifiers()) { + $collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation(); + } - $collector->removeFilter(InternalTransferFilter::class); - $set = $collector->getPaginatedTransactions()->getCollection(); + $collector->setSearchWords($this->words); + $collector->removeFilter(InternalTransferFilter::class); + $collector->addFilter(DoubleTransactionFilter::class); - Log::debug(sprintf('Found %d journals to check. ', $set->count())); + // Most modifiers can be applied to the collector directly. + $collector = $this->applyModifiers($collector); - // Filter transactions that match the given triggers. - $filtered = $set->filter( - function (Transaction $transaction) { - if ($this->matchModifiers($transaction)) { - return $transaction; - } + return $collector->getPaginatedTransactions(); - // return false: - return false; - } - ); - - Log::debug(sprintf('Found %d journals that match.', $filtered->count())); - - // merge: - /** @var Collection $result */ - $result = $result->merge($filtered); - Log::debug(sprintf('Total count is now %d', $result->count())); - - // Update counters - ++$page; - $processed += \count($set); - - Log::debug(sprintf('Page is now %d, processed is %d', $page, $processed)); - - // Check for conditions to finish the loop - $reachedEndOfList = $set->count() < 1; - $foundEnough = $result->count() >= $this->limit; - - Log::debug(sprintf('reachedEndOfList: %s', var_export($reachedEndOfList, true))); - Log::debug(sprintf('foundEnough: %s', var_export($foundEnough, true))); - - // break at some point so the script does not crash: - $currentTime = microtime(true) - $startTime; - Log::debug(sprintf('Have been running for %f seconds.', $currentTime)); - } while (!$reachedEndOfList && !$foundEnough && $currentTime <= 30); - - $result = $result->slice(0, $this->limit); - - return $result; } /** @@ -187,6 +181,10 @@ class Search implements SearchInterface public function setUser(User $user): void { $this->user = $user; + $this->accountRepository->setUser($user); + $this->billRepository->setUser($user); + $this->categoryRepository->setUser($user); + $this->budgetRepository->setUser($user); } /** @@ -197,8 +195,49 @@ class Search implements SearchInterface */ private function applyModifiers(TransactionCollectorInterface $collector): TransactionCollectorInterface { + /* + * TODO: + * 'bill', + */ + foreach ($this->modifiers as $modifier) { switch ($modifier['type']) { + default: + die(sprintf('unsupported modifier: "%s"', $modifier['type'])); + case 'source': + // source can only be asset, liability or revenue account: + $searchTypes = [AccountType::ASSET, AccountType::MORTGAGE, AccountType::LOAN, AccountType::DEBT, AccountType::REVENUE]; + $accounts = $this->accountRepository->searchAccount($modifier['value'], $searchTypes); + if ($accounts->count() > 0) { + $collector->setAccounts($accounts); + } + break; + case 'destination': + // source can only be asset, liability or expense account: + $searchTypes = [AccountType::ASSET, AccountType::MORTGAGE, AccountType::LOAN, AccountType::DEBT, AccountType::EXPENSE]; + $accounts = $this->accountRepository->searchAccount($modifier['value'], $searchTypes); + if ($accounts->count() > 0) { + $collector->setOpposingAccounts($accounts); + } + break; + case 'category': + $result = $this->categoryRepository->searchCategory($modifier['value']); + if ($result->count() > 0) { + $collector->setCategories($result); + } + break; + case 'bill': + $result = $this->billRepository->searchBill($modifier['value']); + if ($result->count() > 0) { + $collector->setBills($result); + } + break; + case 'budget': + $result = $this->budgetRepository->searchBudget($modifier['value']); + if ($result->count() > 0) { + $collector->setBudgets($result); + } + break; case 'amount_is': case 'amount': $amount = app('steam')->positive((string)$modifier['value']); @@ -260,55 +299,4 @@ class Search implements SearchInterface } } } - - /** - * @param Transaction $transaction - * - * @return bool - * - */ - private function matchModifiers(Transaction $transaction): bool - { - Log::debug(sprintf('Now at transaction #%d', $transaction->id)); - // first "modifier" is always the text of the search: - // check descr of journal: - if (\count($this->words) > 0 - && !$this->strposArray(strtolower((string)$transaction->description), $this->words) - && !$this->strposArray(strtolower((string)$transaction->transaction_description), $this->words) - ) { - Log::debug('Description does not match', $this->words); - - return false; - } - - // then a for-each and a switch for every possible other thingie. - foreach ($this->modifiers as $modifier) { - $res = Modifier::apply($modifier, $transaction); - if (false === $res) { - return $res; - } - } - - return true; - } - - /** - * @param string $haystack - * @param array $needle - * - * @return bool - */ - private function strposArray(string $haystack, array $needle): bool - { - if ('' === $haystack) { - return false; - } - foreach ($needle as $what) { - if (false !== stripos($haystack, $what)) { - return true; - } - } - - return false; - } } diff --git a/app/Support/Search/SearchInterface.php b/app/Support/Search/SearchInterface.php index d1d7ebdb71..df8876d5ae 100644 --- a/app/Support/Search/SearchInterface.php +++ b/app/Support/Search/SearchInterface.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace FireflyIII\Support\Search; use FireflyIII\User; +use Illuminate\Pagination\LengthAwarePaginator; use Illuminate\Support\Collection; /** @@ -30,6 +31,11 @@ use Illuminate\Support\Collection; */ interface SearchInterface { + /** + * @return Collection + */ + public function getModifiers(): Collection; + /** * @return string */ @@ -46,9 +52,14 @@ interface SearchInterface public function parseQuery(string $query); /** - * @return Collection + * @return float */ - public function searchTransactions(): Collection; + public function searchTime(): float; + + /** + * @return LengthAwarePaginator + */ + public function searchTransactions(): LengthAwarePaginator; /** * @param int $limit diff --git a/changelog.md b/changelog.md index cb871f415c..47144e7fb1 100644 --- a/changelog.md +++ b/changelog.md @@ -2,6 +2,22 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## [4.7.15 (API 0.9.2)] - 2019-03-02 + +4.7.15 was released to fix some issues upgrading from older versions. + +### Added +- [Issue 2128](https://github.com/firefly-iii/firefly-iii/issues/2128) Support for Postgres SSL + +### Changed +- [Issue 2120](https://github.com/firefly-iii/firefly-iii/issues/2120) Add a missing meta tag, thanks to @lastlink +- Search is a lot faster now. + +### Fixed +- [Issue 2125](https://github.com/firefly-iii/firefly-iii/issues/2125) Decryption issues during upgrade +- [Issue 2130](https://github.com/firefly-iii/firefly-iii/issues/2130) Fixed database migrations and rollbacks. +- [Issue 2135](https://github.com/firefly-iii/firefly-iii/issues/2135) Date fixes in transaction overview + ## [4.7.14 (API 0.9.2)] - 2019-02-24 4.7.14 was released to fix an issue with the Composer installation script. diff --git a/composer.lock b/composer.lock index 1dd343a205..9845e77a5d 100644 --- a/composer.lock +++ b/composer.lock @@ -8,28 +8,32 @@ "packages": [ { "name": "adldap2/adldap2", - "version": "v9.1.4", + "version": "v10.0.3", "source": { "type": "git", "url": "https://github.com/Adldap2/Adldap2.git", - "reference": "e74bf7e3762b35e828179b11eb100da4a12ff701" + "reference": "9e4a41dfd045b6b45b03576e409a99f69dd5dd8e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Adldap2/Adldap2/zipball/e74bf7e3762b35e828179b11eb100da4a12ff701", - "reference": "e74bf7e3762b35e828179b11eb100da4a12ff701", + "url": "https://api.github.com/repos/Adldap2/Adldap2/zipball/9e4a41dfd045b6b45b03576e409a99f69dd5dd8e", + "reference": "9e4a41dfd045b6b45b03576e409a99f69dd5dd8e", "shasum": "" }, "require": { "ext-ldap": "*", "illuminate/contracts": "~5.0", "php": ">=7.0", + "psr/log": "~1.1", "tightenco/collect": "~5.0" }, "require-dev": { "mockery/mockery": "~1.0", "phpunit/phpunit": "~6.0" }, + "suggest": { + "ext-fileinfo": "fileinfo is required when retrieving user encoded thumbnails" + }, "type": "library", "autoload": { "psr-4": { @@ -57,24 +61,24 @@ "ldap", "windows" ], - "time": "2018-12-06T15:03:32+00:00" + "time": "2019-02-20T15:52:32+00:00" }, { "name": "adldap2/adldap2-laravel", - "version": "v5.1.1", + "version": "v5.1.2", "source": { "type": "git", "url": "https://github.com/Adldap2/Adldap2-Laravel.git", - "reference": "293721cd55b9410e274985ec6f869ea0cc499275" + "reference": "b3f5c533f3bda00ba22e8e1b6c29e4b1bb7cc230" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Adldap2/Adldap2-Laravel/zipball/293721cd55b9410e274985ec6f869ea0cc499275", - "reference": "293721cd55b9410e274985ec6f869ea0cc499275", + "url": "https://api.github.com/repos/Adldap2/Adldap2-Laravel/zipball/b3f5c533f3bda00ba22e8e1b6c29e4b1bb7cc230", + "reference": "b3f5c533f3bda00ba22e8e1b6c29e4b1bb7cc230", "shasum": "" }, "require": { - "adldap2/adldap2": "^9.0", + "adldap2/adldap2": "^10.0", "php": ">=7.1" }, "require-dev": { @@ -110,7 +114,7 @@ "laravel", "ldap" ], - "time": "2019-01-08T15:37:47+00:00" + "time": "2019-02-27T07:09:43+00:00" }, { "name": "bacon/bacon-qr-code", @@ -396,26 +400,26 @@ }, { "name": "davejamesmiller/laravel-breadcrumbs", - "version": "5.2.0", + "version": "5.2.1", "source": { "type": "git", "url": "https://github.com/davejamesmiller/laravel-breadcrumbs.git", - "reference": "e2ed8b0992231ebc61480c63f095a2cf3b8829a1" + "reference": "6465e8710341578092fdd8aea24319d4f53ab27c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/davejamesmiller/laravel-breadcrumbs/zipball/e2ed8b0992231ebc61480c63f095a2cf3b8829a1", - "reference": "e2ed8b0992231ebc61480c63f095a2cf3b8829a1", + "url": "https://api.github.com/repos/davejamesmiller/laravel-breadcrumbs/zipball/6465e8710341578092fdd8aea24319d4f53ab27c", + "reference": "6465e8710341578092fdd8aea24319d4f53ab27c", "shasum": "" }, "require": { - "illuminate/support": "5.6.*|5.7.*", - "illuminate/view": "5.6.*|5.7.*", + "illuminate/support": "5.6.*|5.7.*|5.8.*", + "illuminate/view": "5.6.*|5.7.*|5.8.*", "php": ">=7.1.3" }, "require-dev": { - "laravel/framework": "5.6.*|5.7.*", - "orchestra/testbench": "3.6.*|3.7.*", + "laravel/framework": "5.6.*|5.7.*|5.8.*", + "orchestra/testbench": "3.6.*|3.7.*|3.8.*", "php-coveralls/php-coveralls": "^1.0", "phpunit/phpunit": "7.*" }, @@ -450,7 +454,7 @@ "keywords": [ "laravel" ], - "time": "2018-10-30T22:06:33+00:00" + "time": "2019-02-27T13:09:37+00:00" }, { "name": "defuse/php-encryption", @@ -1304,16 +1308,16 @@ }, { "name": "laravel/framework", - "version": "v5.7.27", + "version": "v5.7.28", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "688fbfa889d43f392825b381ad3981847120fdfa" + "reference": "8e69728f1c80a024588adbd24c65c4fcf9aa9192" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/688fbfa889d43f392825b381ad3981847120fdfa", - "reference": "688fbfa889d43f392825b381ad3981847120fdfa", + "url": "https://api.github.com/repos/laravel/framework/zipball/8e69728f1c80a024588adbd24c65c4fcf9aa9192", + "reference": "8e69728f1c80a024588adbd24c65c4fcf9aa9192", "shasum": "" }, "require": { @@ -1386,7 +1390,7 @@ "mockery/mockery": "^1.0", "moontoast/math": "^1.1", "orchestra/testbench-core": "3.7.*", - "pda/pheanstalk": "^3.0", + "pda/pheanstalk": "^3.0|^4.0", "phpunit/phpunit": "^7.5", "predis/predis": "^1.1.1", "symfony/css-selector": "^4.1", @@ -1408,7 +1412,7 @@ "league/flysystem-sftp": "Required to use the Flysystem SFTP driver (^1.0).", "moontoast/math": "Required to use ordered UUIDs (^1.1).", "nexmo/client": "Required to use the Nexmo transport (^1.0).", - "pda/pheanstalk": "Required to use the beanstalk queue driver (^3.0).", + "pda/pheanstalk": "Required to use the beanstalk queue driver (^3.0|^4.0).", "predis/predis": "Required to use the redis cache and queue drivers (^1.0).", "pusher/pusher-php-server": "Required to use the Pusher broadcast driver (^3.0).", "symfony/css-selector": "Required to use some of the crawler integration testing tools (^4.1).", @@ -1446,7 +1450,7 @@ "framework", "laravel" ], - "time": "2019-02-19T14:37:47+00:00" + "time": "2019-02-26T15:41:34+00:00" }, { "name": "laravel/nexmo-notification-channel", @@ -4645,16 +4649,16 @@ }, { "name": "tightenco/collect", - "version": "v5.7.26", + "version": "v5.8.2", "source": { "type": "git", "url": "https://github.com/tightenco/collect.git", - "reference": "c1a36a2a8a0aa731c1acdcd83f57724ffe630d00" + "reference": "9e431d3ba84ff02183bbb6da07410d59ef769f9b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/tightenco/collect/zipball/c1a36a2a8a0aa731c1acdcd83f57724ffe630d00", - "reference": "c1a36a2a8a0aa731c1acdcd83f57724ffe630d00", + "url": "https://api.github.com/repos/tightenco/collect/zipball/9e431d3ba84ff02183bbb6da07410d59ef769f9b", + "reference": "9e431d3ba84ff02183bbb6da07410d59ef769f9b", "shasum": "" }, "require": { @@ -4691,7 +4695,7 @@ "collection", "laravel" ], - "time": "2019-02-13T19:40:13+00:00" + "time": "2019-02-26T18:45:33+00:00" }, { "name": "tijsverkoyen/css-to-inline-styles", @@ -4925,30 +4929,30 @@ "packages-dev": [ { "name": "barryvdh/laravel-ide-helper", - "version": "v2.5.3", + "version": "v2.6.0", "source": { "type": "git", "url": "https://github.com/barryvdh/laravel-ide-helper.git", - "reference": "3d7f1240896a075aa23b13f82dfcbe165dadeef2" + "reference": "754bb4d075d7fb2b23b1a416802c0e45884df495" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/barryvdh/laravel-ide-helper/zipball/3d7f1240896a075aa23b13f82dfcbe165dadeef2", - "reference": "3d7f1240896a075aa23b13f82dfcbe165dadeef2", + "url": "https://api.github.com/repos/barryvdh/laravel-ide-helper/zipball/754bb4d075d7fb2b23b1a416802c0e45884df495", + "reference": "754bb4d075d7fb2b23b1a416802c0e45884df495", "shasum": "" }, "require": { "barryvdh/reflection-docblock": "^2.0.6", "composer/composer": "^1.6", - "illuminate/console": "^5.5,<5.8", - "illuminate/filesystem": "^5.5,<5.8", - "illuminate/support": "^5.5,<5.8", + "illuminate/console": "^5.5,<5.9", + "illuminate/filesystem": "^5.5,<5.9", + "illuminate/support": "^5.5,<5.9", "php": ">=7" }, "require-dev": { "doctrine/dbal": "~2.3", - "illuminate/config": "^5.1,<5.8", - "illuminate/view": "^5.1,<5.8", + "illuminate/config": "^5.1,<5.9", + "illuminate/view": "^5.1,<5.9", "phpro/grumphp": "^0.14", "phpunit/phpunit": "4.*", "scrutinizer/ocular": "~1.1", @@ -4960,7 +4964,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.5-dev" + "dev-master": "2.6-dev" }, "laravel": { "providers": [ @@ -4995,7 +4999,7 @@ "phpstorm", "sublime" ], - "time": "2018-12-19T12:12:05+00:00" + "time": "2019-02-18T19:54:27+00:00" }, { "name": "barryvdh/reflection-docblock", @@ -6531,12 +6535,12 @@ "source": { "type": "git", "url": "https://github.com/Roave/SecurityAdvisories.git", - "reference": "614a9db1df6be4349544311096f8d48ca067ccbb" + "reference": "4e04718428742618a4bf24dafca45b8645c9320d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/614a9db1df6be4349544311096f8d48ca067ccbb", - "reference": "614a9db1df6be4349544311096f8d48ca067ccbb", + "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/4e04718428742618a4bf24dafca45b8645c9320d", + "reference": "4e04718428742618a4bf24dafca45b8645c9320d", "shasum": "" }, "conflict": { @@ -6571,91 +6575,8 @@ "doctrine/mongodb-odm-bundle": ">=2,<3.0.1", "doctrine/orm": ">=2,<2.4.8|>=2.5,<2.5.1", "dompdf/dompdf": ">=0.6,<0.6.2", - "drupal/acquia_connector": ">=1,<1.16", - "drupal/autologout": ">=4,<4.5", - "drupal/backup_migrate": ">=3,<3.4", - "drupal/bealestreet": ">=1,<1.2", - "drupal/bible": ">=1,<1.7", - "drupal/bing_autosuggest_api": ">=1,<1.1", - "drupal/bootstrap": ">=3,<3.14", - "drupal/brilliant_gallery": ">=1,<1.10", - "drupal/ckeditor_uploadimage": ">=1,<1.5", - "drupal/cleantalk": ">=2,<2.7", - "drupal/cloud": ">=1,<1.7", - "drupal/commerce": ">=2,<2.9", - "drupal/commerce_custom_order_status": ">=1,<1.1", - "drupal/commerce_klarna_checkout": ">=1,<1.5", - "drupal/config_perms": ">=1,<1.1|>=2,<2.2", - "drupal/config_update": ">=1,<1.5", "drupal/core": ">=7,<7.62|>=8,<8.5.11|>=8.6,<8.6.10", - "drupal/datereminder": ">=1,<1.15", - "drupal/decoupled_router": ">=1,<1.2", - "drupal/domain_integration": ">=1,<1.2", "drupal/drupal": ">=7,<7.62|>=8,<8.5.11|>=8.6,<8.6.10", - "drupal/entity": ">=1,<1.9", - "drupal/entity_ref_tab_formatter": ">=1,<1.3", - "drupal/entityqueue_taxonomy": ">=1,<1.1", - "drupal/esign": ">=1,<1.10", - "drupal/eu_cookie_compliance": ">=1,<1.1", - "drupal/exif": ">=1,<1.1", - "drupal/feedback_collect": ">=1,<1.6", - "drupal/filefield_paths": ">=1,<1.1", - "drupal/filefield_sources": ">=1,<1.11", - "drupal/focal_point": ">=1,<1.2", - "drupal/fontawesome": ">=2,<2.12", - "drupal/fraction": ">=1,<1.2", - "drupal/gathercontent": ">=3,<3.5", - "drupal/genpass": ">=1,<1.1", - "drupal/hosting_https": ">=3,<3.170", - "drupal/jsonapi": ">=1,<1.16", - "drupal/lightbox2": ">=2,<2.11", - "drupal/link": ">=1,<1.6", - "drupal/litejazz": ">=2,<2.3", - "drupal/mailhandler": ">=2,<2.11", - "drupal/mass_pwreset": ">=1,<1.1", - "drupal/me": ">=1,<1.3", - "drupal/media": ">=2,<2.19", - "drupal/menu_export": ">=1,<1.2", - "drupal/metatag": ">=1,<1.8", - "drupal/miniorange_oauth_client": ">=1,<1.21", - "drupal/moneysuite": ">=10,<10.4", - "drupal/mosaik": ">=1,<1.2", - "drupal/netforum_authentication": ">=1,<1.1", - "drupal/newsflash": ">=2,<2.6", - "drupal/node_feedback": ">=1,<1.3", - "drupal/node_view_permissions": ">=1,<1.1", - "drupal/nucleus": ">=1,<1.6", - "drupal/nvp": ">=1,<1.1", - "drupal/panels_breadcrumbs": ">=2,<2.4", - "drupal/panopoly_core": ">=1,<1.49", - "drupal/paragraphs": ">=1,<1.6", - "drupal/password_policy": ">=1,<1.16", - "drupal/permissions_by_term": ">=1,<1.35", - "drupal/phonefield": ">=1,<1.1", - "drupal/phpconfig": ">=1,<1.1", - "drupal/preview_link": ">=1,<1.1", - "drupal/print": ">=2,<2.1", - "drupal/provision": ">=3,<3.170", - "drupal/pubdlcnt": ">=1,<1.3", - "drupal/renderkit": ">=1,<1.6", - "drupal/responsive_menus": ">=1,<1.7", - "drupal/restws": ">=2,<2.8", - "drupal/sagepay_payment": ">=1,<1.5", - "drupal/salesforce": ">=3,<3.1", - "drupal/search_api_solr": ">=1,<1.14", - "drupal/search_autocomplete": ">=4,<4.8", - "drupal/services_sso_client": ">=1,<1.6", - "drupal/stacks": ">=1,<1.1", - "drupal/tapestry": ">=2,<2.2", - "drupal/term_reference_tree": ">=1,<1.11", - "drupal/tfa_basic": ">=1,<1.1", - "drupal/tft": ">=1,<1.1", - "drupal/tmgmt": ">=1,<1.7", - "drupal/uuid": ">=1,<1.1", - "drupal/video": ">=1,<1.4", - "drupal/workbench_moderation": ">=1,<1.4", - "drupal/yandex_metrics": ">=3,<3.1", - "drupal/zircon": ">=1,<1.2", "erusev/parsedown": "<1.7", "ezsystems/ezpublish-kernel": ">=5.3,<5.3.12.1|>=5.4,<5.4.13.1|>=6,<6.7.9.1|>=6.8,<6.13.5.1|>=7,<7.2.4.1|>=7.3,<7.3.2.1", "ezsystems/ezpublish-legacy": ">=5.3,<5.3.12.6|>=5.4,<5.4.12.3|>=2011,<2017.12.4.3|>=2018.6,<2018.6.1.4|>=2018.9,<2018.9.1.3", @@ -6752,7 +6673,7 @@ "symfony/yaml": ">=2,<2.0.22|>=2.1,<2.1.7", "tecnickcom/tcpdf": "<6.2.22", "thelia/backoffice-default-template": ">=2.1,<2.1.2", - "thelia/thelia": ">=2.1,<2.1.2|>=2.1.0-beta1,<2.1.3", + "thelia/thelia": ">=2.1.0-beta1,<2.1.3|>=2.1,<2.1.2", "theonedemon/phpwhois": "<=4.2.5", "titon/framework": ">=0,<9.9.99", "truckersmp/phpwhois": "<=4.3.1", @@ -6810,7 +6731,7 @@ } ], "description": "Prevents installation of composer packages with known security vulnerabilities: no API, simply require it", - "time": "2019-02-22T18:40:39+00:00" + "time": "2019-02-26T21:14:50+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", diff --git a/config/database.php b/config/database.php index fffe561ea3..92002884ba 100644 --- a/config/database.php +++ b/config/database.php @@ -60,16 +60,19 @@ return [ 'engine' => 'InnoDB', ], 'pgsql' => [ - 'driver' => 'pgsql', - 'host' => envNonEmpty('DB_HOST', $host), - 'port' => envNonEmpty('DB_PORT', '5432'), - 'database' => envNonEmpty('DB_DATABASE', $database), - 'username' => envNonEmpty('DB_USERNAME', $username), - 'password' => env('DB_PASSWORD', $password), - 'charset' => 'utf8', - 'prefix' => '', - 'schema' => 'public', - 'sslmode' => 'prefer', + 'driver' => 'pgsql', + 'host' => envNonEmpty('DB_HOST', $host), + 'port' => envNonEmpty('DB_PORT', '5432'), + 'database' => envNonEmpty('DB_DATABASE', $database), + 'username' => envNonEmpty('DB_USERNAME', $username), + 'password' => env('DB_PASSWORD', $password), + 'charset' => 'utf8', + 'prefix' => '', + 'schema' => 'public', + 'sslmode' => envNonEmpty('PGSQL_SSL_MODE', 'prefer'), + 'sslcert' => envNonEmpty('PGSQL_SSL_CERT'), + 'sslkey' => envNonEmpty('PGSQL_SSL_KEY'), + 'sslrootcert' => envNonEmpty('PGSQL_SSL_ROOT_CERT'), ], 'sqlsrv' => [ 'driver' => 'sqlsrv', diff --git a/config/firefly.php b/config/firefly.php index 6b80c14d1a..15291bcc9d 100644 --- a/config/firefly.php +++ b/config/firefly.php @@ -93,7 +93,7 @@ return [ 'is_demo_site' => false, ], 'encryption' => null === env('USE_ENCRYPTION') || env('USE_ENCRYPTION') === true, - 'version' => '4.7.14', + 'version' => '4.7.15', 'api_version' => '0.9.2', 'db_version' => 9, 'maxUploadSize' => 15242880, diff --git a/database/migrations/2016_06_16_000000_create_support_tables.php b/database/migrations/2016_06_16_000000_create_support_tables.php index 0adc8d6ddc..a5f0f1cad0 100644 --- a/database/migrations/2016_06_16_000000_create_support_tables.php +++ b/database/migrations/2016_06_16_000000_create_support_tables.php @@ -31,7 +31,7 @@ class CreateSupportTables extends Migration /** * Reverse the migrations. */ - public function down() + public function down(): void { Schema::drop('account_types'); Schema::drop('transaction_currencies'); @@ -50,7 +50,7 @@ class CreateSupportTables extends Migration * * @SuppressWarnings(PHPMD.ShortMethodName) */ - public function up() + public function up(): void { $this->createAccountTypeTable(); $this->createCurrencyTable(); @@ -67,7 +67,7 @@ class CreateSupportTables extends Migration /** * */ - private function createAccountTypeTable() + private function createAccountTypeTable(): void { if (!Schema::hasTable('account_types')) { Schema::create( @@ -84,7 +84,7 @@ class CreateSupportTables extends Migration } } - private function createConfigurationTable() + private function createConfigurationTable(): void { if (!Schema::hasTable('configuration')) { Schema::create( @@ -104,7 +104,7 @@ class CreateSupportTables extends Migration /** * */ - private function createCurrencyTable() + private function createCurrencyTable(): void { if (!Schema::hasTable('transaction_currencies')) { Schema::create( @@ -127,7 +127,7 @@ class CreateSupportTables extends Migration /** * */ - private function createJobsTable() + private function createJobsTable(): void { if (!Schema::hasTable('jobs')) { Schema::create( @@ -151,7 +151,7 @@ class CreateSupportTables extends Migration /** * */ - private function createPasswordTable() + private function createPasswordTable(): void { if (!Schema::hasTable('password_resets')) { Schema::create( @@ -169,7 +169,7 @@ class CreateSupportTables extends Migration /** * */ - private function createPermissionRoleTable() + private function createPermissionRoleTable(): void { if (!Schema::hasTable('permission_role')) { Schema::create( @@ -190,7 +190,7 @@ class CreateSupportTables extends Migration /** * */ - private function createPermissionsTable() + private function createPermissionsTable(): void { if (!Schema::hasTable('permissions')) { Schema::create( @@ -209,7 +209,7 @@ class CreateSupportTables extends Migration /** * */ - private function createRolesTable() + private function createRolesTable(): void { if (!Schema::hasTable('roles')) { Schema::create( @@ -228,7 +228,7 @@ class CreateSupportTables extends Migration /** * */ - private function createSessionsTable() + private function createSessionsTable(): void { if (!Schema::hasTable('sessions')) { Schema::create( @@ -248,7 +248,7 @@ class CreateSupportTables extends Migration /** * */ - private function createTransactionTypeTable() + private function createTransactionTypeTable(): void { if (!Schema::hasTable('transaction_types')) { Schema::create( diff --git a/database/migrations/2016_06_16_000001_create_users_table.php b/database/migrations/2016_06_16_000001_create_users_table.php index 551bfa748f..14c749f908 100644 --- a/database/migrations/2016_06_16_000001_create_users_table.php +++ b/database/migrations/2016_06_16_000001_create_users_table.php @@ -31,7 +31,7 @@ class CreateUsersTable extends Migration /** * Reverse the migrations. */ - public function down() + public function down(): void { Schema::drop('users'); } @@ -41,7 +41,7 @@ class CreateUsersTable extends Migration * * @SuppressWarnings(PHPMD.ShortMethodName) */ - public function up() + public function up(): void { if (!Schema::hasTable('users')) { Schema::create( diff --git a/database/migrations/2016_06_16_000002_create_main_tables.php b/database/migrations/2016_06_16_000002_create_main_tables.php index 09e547b800..96d580a757 100644 --- a/database/migrations/2016_06_16_000002_create_main_tables.php +++ b/database/migrations/2016_06_16_000002_create_main_tables.php @@ -31,7 +31,7 @@ class CreateMainTables extends Migration /** * Reverse the migrations. */ - public function down() + public function down(): void { Schema::drop('account_meta'); Schema::drop('piggy_bank_repetitions'); @@ -68,7 +68,7 @@ class CreateMainTables extends Migration * * @SuppressWarnings(PHPMD.ShortMethodName) */ - public function up() + public function up(): void { $this->createAccountTables(); $this->createPiggyBanksTable(); @@ -87,7 +87,7 @@ class CreateMainTables extends Migration /** * */ - private function createAccountTables() + private function createAccountTables(): void { if (!Schema::hasTable('accounts')) { Schema::create( @@ -127,7 +127,7 @@ class CreateMainTables extends Migration /** * */ - private function createAttachmentsTable() + private function createAttachmentsTable(): void { if (!Schema::hasTable('attachments')) { Schema::create( @@ -158,7 +158,7 @@ class CreateMainTables extends Migration /** * */ - private function createBillsTable() + private function createBillsTable(): void { if (!Schema::hasTable('bills')) { Schema::create( @@ -190,7 +190,7 @@ class CreateMainTables extends Migration /** * @SuppressWarnings(PHPMD.ExcessiveMethodLength) // cannot be helped. */ - private function createBudgetTables() + private function createBudgetTables(): void { if (!Schema::hasTable('budgets')) { Schema::create( @@ -241,7 +241,7 @@ class CreateMainTables extends Migration /** * */ - private function createCategoriesTable() + private function createCategoriesTable(): void { if (!Schema::hasTable('categories')) { Schema::create( @@ -264,7 +264,7 @@ class CreateMainTables extends Migration /** * */ - private function createExportJobsTable() + private function createExportJobsTable(): void { if (!Schema::hasTable('export_jobs')) { Schema::create( @@ -300,7 +300,7 @@ class CreateMainTables extends Migration /** * */ - private function createPiggyBanksTable() + private function createPiggyBanksTable(): void { if (!Schema::hasTable('piggy_banks')) { Schema::create( @@ -341,7 +341,7 @@ class CreateMainTables extends Migration /** * */ - private function createPreferencesTable() + private function createPreferencesTable(): void { if (!Schema::hasTable('preferences')) { Schema::create( @@ -362,7 +362,7 @@ class CreateMainTables extends Migration /** * */ - private function createRoleTable() + private function createRoleTable(): void { if (!Schema::hasTable('role_user')) { Schema::create( @@ -384,7 +384,7 @@ class CreateMainTables extends Migration * @SuppressWarnings(PHPMD.ExcessiveMethodLength) // cannot be helped. * @SuppressWarnings(PHPMD.CyclomaticComplexity) // its exactly five */ - private function createRuleTables() + private function createRuleTables(): void { if (!Schema::hasTable('rule_groups')) { Schema::create( @@ -472,7 +472,7 @@ class CreateMainTables extends Migration /** * */ - private function createTagsTable() + private function createTagsTable(): void { if (!Schema::hasTable('tags')) { Schema::create( @@ -503,7 +503,7 @@ class CreateMainTables extends Migration * @SuppressWarnings(PHPMD.NPathComplexity) // cannot be helped * @SuppressWarnings(PHPMD.CyclomaticComplexity) // its exactly five */ - private function createTransactionTables() + private function createTransactionTables(): void { if (!Schema::hasTable('transaction_journals')) { Schema::create( diff --git a/database/migrations/2016_08_25_091522_changes_for_3101.php b/database/migrations/2016_08_25_091522_changes_for_3101.php index 5fabe0ffe0..d859fa0424 100644 --- a/database/migrations/2016_08_25_091522_changes_for_3101.php +++ b/database/migrations/2016_08_25_091522_changes_for_3101.php @@ -31,8 +31,14 @@ class ChangesFor3101 extends Migration /** * Reverse the migrations. */ - public function down() + public function down(): void { + Schema::table( + 'import_jobs', + function (Blueprint $table) { + $table->dropColumn('extended_status'); + } + ); } /** @@ -40,7 +46,7 @@ class ChangesFor3101 extends Migration * * @SuppressWarnings(PHPMD.ShortMethodName) */ - public function up() + public function up(): void { Schema::table( 'import_jobs', diff --git a/database/migrations/2016_09_12_121359_fix_nullables.php b/database/migrations/2016_09_12_121359_fix_nullables.php index 606e08f4b9..7c7b77a308 100644 --- a/database/migrations/2016_09_12_121359_fix_nullables.php +++ b/database/migrations/2016_09_12_121359_fix_nullables.php @@ -31,7 +31,7 @@ class FixNullables extends Migration /** * Reverse the migrations. */ - public function down() + public function down(): void { } @@ -40,7 +40,7 @@ class FixNullables extends Migration * * @SuppressWarnings(PHPMD.ShortMethodName) */ - public function up() + public function up(): void { Schema::table( 'rule_groups', diff --git a/database/migrations/2016_10_09_150037_expand_transactions_table.php b/database/migrations/2016_10_09_150037_expand_transactions_table.php index a6ae3345a2..10e2dbf9e7 100644 --- a/database/migrations/2016_10_09_150037_expand_transactions_table.php +++ b/database/migrations/2016_10_09_150037_expand_transactions_table.php @@ -31,8 +31,14 @@ class ExpandTransactionsTable extends Migration /** * Reverse the migrations. */ - public function down() + public function down(): void { + Schema::table( + 'transactions', + function (Blueprint $table) { + $table->dropColumn('identifier'); + } + ); } /** @@ -40,7 +46,7 @@ class ExpandTransactionsTable extends Migration * * @SuppressWarnings(PHPMD.ShortMethodName) */ - public function up() + public function up(): void { Schema::table( 'transactions', diff --git a/database/migrations/2016_10_22_075804_changes_for_v410.php b/database/migrations/2016_10_22_075804_changes_for_v410.php index 227d40732e..132f350b32 100644 --- a/database/migrations/2016_10_22_075804_changes_for_v410.php +++ b/database/migrations/2016_10_22_075804_changes_for_v410.php @@ -31,7 +31,7 @@ class ChangesForV410 extends Migration /** * Reverse the migrations. */ - public function down() + public function down(): void { Schema::dropIfExists('notes'); } @@ -41,7 +41,7 @@ class ChangesForV410 extends Migration * * @SuppressWarnings(PHPMD.ShortMethodName) */ - public function up() + public function up(): void { Schema::create( 'notes', diff --git a/database/migrations/2016_11_24_210552_changes_for_v420.php b/database/migrations/2016_11_24_210552_changes_for_v420.php index 9f209d531d..456c9d60b9 100644 --- a/database/migrations/2016_11_24_210552_changes_for_v420.php +++ b/database/migrations/2016_11_24_210552_changes_for_v420.php @@ -31,8 +31,14 @@ class ChangesForV420 extends Migration /** * Reverse the migrations. */ - public function down() + public function down(): void { + Schema::table( + 'journal_meta', + function (Blueprint $table) { + $table->dropSoftDeletes(); + } + ); } /** @@ -40,7 +46,7 @@ class ChangesForV420 extends Migration * * @SuppressWarnings(PHPMD.ShortMethodName) */ - public function up() + public function up(): void { Schema::table( 'journal_meta', diff --git a/database/migrations/2016_12_22_150431_changes_for_v430.php b/database/migrations/2016_12_22_150431_changes_for_v430.php index f35038fcb8..8ddf113b4f 100644 --- a/database/migrations/2016_12_22_150431_changes_for_v430.php +++ b/database/migrations/2016_12_22_150431_changes_for_v430.php @@ -31,7 +31,7 @@ class ChangesForV430 extends Migration /** * Reverse the migrations. */ - public function down() + public function down(): void { Schema::dropIfExists('available_budgets'); } @@ -41,7 +41,7 @@ class ChangesForV430 extends Migration * * @SuppressWarnings(PHPMD.ShortMethodName) */ - public function up() + public function up(): void { Schema::create( 'available_budgets', diff --git a/database/migrations/2016_12_28_203205_changes_for_v431.php b/database/migrations/2016_12_28_203205_changes_for_v431.php index 10168fb337..1d276d6cee 100644 --- a/database/migrations/2016_12_28_203205_changes_for_v431.php +++ b/database/migrations/2016_12_28_203205_changes_for_v431.php @@ -31,7 +31,7 @@ class ChangesForV431 extends Migration /** * Reverse the migrations. */ - public function down() + public function down(): void { // reinstate "repeats" and "repeat_freq". Schema::table( @@ -47,6 +47,14 @@ class ChangesForV431 extends Migration } ); + // change field "start_date" to "startdate" + Schema::table( + 'budget_limits', + function (Blueprint $table) { + $table->renameColumn('start_date', 'startdate'); + } + ); + // remove date field "end_date" Schema::table( 'budget_limits', @@ -54,6 +62,13 @@ class ChangesForV431 extends Migration $table->dropColumn('end_date'); } ); + // remove decimal places + Schema::table( + 'transaction_currencies', + function (Blueprint $table) { + $table->dropColumn('decimal_places'); + } + ); } /** @@ -61,7 +76,7 @@ class ChangesForV431 extends Migration * * @SuppressWarnings(PHPMD.ShortMethodName) */ - public function up() + public function up(): void { // add decimal places to "transaction currencies". Schema::table( diff --git a/database/migrations/2017_04_13_163623_changes_for_v440.php b/database/migrations/2017_04_13_163623_changes_for_v440.php index c5829ec619..e6175553a0 100644 --- a/database/migrations/2017_04_13_163623_changes_for_v440.php +++ b/database/migrations/2017_04_13_163623_changes_for_v440.php @@ -31,11 +31,23 @@ class ChangesForV440 extends Migration /** * Reverse the migrations. */ - public function down() + public function down(): void { if (Schema::hasTable('currency_exchange_rates')) { Schema::drop('currency_exchange_rates'); } + + Schema::table( + 'transactions', + function (Blueprint $table) { + + // cannot drop foreign keys in SQLite: + if ('sqlite' !== config('database.default')) { + $table->dropForeign('transactions_transaction_currency_id_foreign'); + } + $table->dropColumn('transaction_currency_id'); + } + ); } /** @@ -43,7 +55,7 @@ class ChangesForV440 extends Migration * * @SuppressWarnings(PHPMD.ShortMethodName) */ - public function up() + public function up(): void { if (!Schema::hasTable('currency_exchange_rates')) { Schema::create( diff --git a/database/migrations/2017_06_02_105232_changes_for_v450.php b/database/migrations/2017_06_02_105232_changes_for_v450.php index 4df00f1393..39c3ec1c9b 100644 --- a/database/migrations/2017_06_02_105232_changes_for_v450.php +++ b/database/migrations/2017_06_02_105232_changes_for_v450.php @@ -31,8 +31,20 @@ class ChangesForV450 extends Migration /** * Reverse the migrations. */ - public function down() + public function down(): void { + Schema::table( + 'transactions', + function (Blueprint $table) { + $table->dropColumn('foreign_amount'); + + // cannot drop foreign keys in SQLite: + if ('sqlite' !== config('database.default')) { + $table->dropForeign('transactions_foreign_currency_id_foreign'); + } + $table->dropColumn('foreign_currency_id'); + } + ); } /** @@ -40,7 +52,7 @@ class ChangesForV450 extends Migration * * @SuppressWarnings(PHPMD.ShortMethodName) */ - public function up() + public function up(): void { // add "foreign_amount" to transactions Schema::table( diff --git a/database/migrations/2017_08_20_062014_changes_for_v470.php b/database/migrations/2017_08_20_062014_changes_for_v470.php index fc42fba920..9088da2593 100644 --- a/database/migrations/2017_08_20_062014_changes_for_v470.php +++ b/database/migrations/2017_08_20_062014_changes_for_v470.php @@ -32,7 +32,7 @@ class ChangesForV470 extends Migration /** * Reverse the migrations. */ - public function down() + public function down(): void { Schema::dropIfExists('journal_links'); Schema::dropIfExists('link_types'); @@ -43,7 +43,7 @@ class ChangesForV470 extends Migration * * @SuppressWarnings(PHPMD.ShortMethodName) */ - public function up() + public function up(): void { if (!Schema::hasTable('link_types')) { Schema::create( diff --git a/database/migrations/2017_11_04_170844_changes_for_v470a.php b/database/migrations/2017_11_04_170844_changes_for_v470a.php index b2d1f603cc..b9d2ebb20e 100644 --- a/database/migrations/2017_11_04_170844_changes_for_v470a.php +++ b/database/migrations/2017_11_04_170844_changes_for_v470a.php @@ -32,8 +32,14 @@ class ChangesForV470a extends Migration /** * Reverse the migrations. */ - public function down() + public function down(): void { + Schema::table( + 'transactions', + function (Blueprint $table) { + $table->dropColumn('reconciled'); + } + ); } /** @@ -41,7 +47,7 @@ class ChangesForV470a extends Migration * * @SuppressWarnings(PHPMD.ShortMethodName) */ - public function up() + public function up(): void { Schema::table( 'transactions', diff --git a/database/migrations/2018_01_01_000001_create_oauth_auth_codes_table.php b/database/migrations/2018_01_01_000001_create_oauth_auth_codes_table.php index 068f187e0d..4d88023dc6 100644 --- a/database/migrations/2018_01_01_000001_create_oauth_auth_codes_table.php +++ b/database/migrations/2018_01_01_000001_create_oauth_auth_codes_table.php @@ -34,7 +34,7 @@ class CreateOauthAuthCodesTable extends Migration /** * Reverse the migrations. */ - public function down() + public function down(): void { Schema::drop('oauth_auth_codes'); } @@ -42,7 +42,7 @@ class CreateOauthAuthCodesTable extends Migration /** * Run the migrations. */ - public function up() + public function up(): void { Schema::create( 'oauth_auth_codes', function (Blueprint $table) { diff --git a/database/migrations/2018_01_01_000002_create_oauth_access_tokens_table.php b/database/migrations/2018_01_01_000002_create_oauth_access_tokens_table.php index 00889896fb..47101b5a2e 100644 --- a/database/migrations/2018_01_01_000002_create_oauth_access_tokens_table.php +++ b/database/migrations/2018_01_01_000002_create_oauth_access_tokens_table.php @@ -34,7 +34,7 @@ class CreateOauthAccessTokensTable extends Migration /** * Reverse the migrations. */ - public function down() + public function down(): void { Schema::drop('oauth_access_tokens'); } @@ -42,7 +42,7 @@ class CreateOauthAccessTokensTable extends Migration /** * Run the migrations. */ - public function up() + public function up(): void { Schema::create( 'oauth_access_tokens', function (Blueprint $table) { diff --git a/database/migrations/2018_01_01_000003_create_oauth_refresh_tokens_table.php b/database/migrations/2018_01_01_000003_create_oauth_refresh_tokens_table.php index 1d6199d904..b154666881 100644 --- a/database/migrations/2018_01_01_000003_create_oauth_refresh_tokens_table.php +++ b/database/migrations/2018_01_01_000003_create_oauth_refresh_tokens_table.php @@ -34,7 +34,7 @@ class CreateOauthRefreshTokensTable extends Migration /** * Reverse the migrations. */ - public function down() + public function down(): void { Schema::drop('oauth_refresh_tokens'); } @@ -42,7 +42,7 @@ class CreateOauthRefreshTokensTable extends Migration /** * Run the migrations. */ - public function up() + public function up(): void { Schema::create( 'oauth_refresh_tokens', function (Blueprint $table) { diff --git a/database/migrations/2018_01_01_000004_create_oauth_clients_table.php b/database/migrations/2018_01_01_000004_create_oauth_clients_table.php index cbd08eb1db..16c5bc6c87 100644 --- a/database/migrations/2018_01_01_000004_create_oauth_clients_table.php +++ b/database/migrations/2018_01_01_000004_create_oauth_clients_table.php @@ -34,7 +34,7 @@ class CreateOauthClientsTable extends Migration /** * Reverse the migrations. */ - public function down() + public function down(): void { Schema::drop('oauth_clients'); } @@ -42,7 +42,7 @@ class CreateOauthClientsTable extends Migration /** * Run the migrations. */ - public function up() + public function up(): void { Schema::create( 'oauth_clients', function (Blueprint $table) { diff --git a/database/migrations/2018_01_01_000005_create_oauth_personal_access_clients_table.php b/database/migrations/2018_01_01_000005_create_oauth_personal_access_clients_table.php index adc9006492..73e26aff39 100644 --- a/database/migrations/2018_01_01_000005_create_oauth_personal_access_clients_table.php +++ b/database/migrations/2018_01_01_000005_create_oauth_personal_access_clients_table.php @@ -37,6 +37,7 @@ class CreateOauthPersonalAccessClientsTable extends Migration public function down(): void { Schema::drop('oauth_personal_access_clients'); + } /** diff --git a/database/migrations/2018_03_19_141348_changes_for_v472.php b/database/migrations/2018_03_19_141348_changes_for_v472.php index 9a7c4b5a79..abb3afe3ed 100644 --- a/database/migrations/2018_03_19_141348_changes_for_v472.php +++ b/database/migrations/2018_03_19_141348_changes_for_v472.php @@ -37,7 +37,18 @@ class ChangesForV472 extends Migration */ public function down(): void { - // + Schema::table( + 'attachments', + function (Blueprint $table) { + $table->text('notes')->nullable(); + } + ); + Schema::table( + 'budgets', + function (Blueprint $table) { + $table->dropColumn('order'); + } + ); } /** diff --git a/database/migrations/2018_04_07_210913_changes_for_v473.php b/database/migrations/2018_04_07_210913_changes_for_v473.php index 37b70d325c..3ebbb5fe6c 100644 --- a/database/migrations/2018_04_07_210913_changes_for_v473.php +++ b/database/migrations/2018_04_07_210913_changes_for_v473.php @@ -38,7 +38,25 @@ class ChangesForV473 extends Migration */ public function down(): void { + Schema::table( + 'bills', + function (Blueprint $table) { + // cannot drop foreign keys in SQLite: + if ('sqlite' !== config('database.default')) { + $table->dropForeign('bills_transaction_currency_id_foreign'); + } + $table->dropColumn('transaction_currency_id'); + } + ); + + + Schema::table( + 'rules', + function (Blueprint $table) { + $table->dropColumn('strict'); + } + ); } /** diff --git a/database/migrations/2018_04_29_174524_changes_for_v474.php b/database/migrations/2018_04_29_174524_changes_for_v474.php index 2cda9d050b..dfa7e722ac 100644 --- a/database/migrations/2018_04_29_174524_changes_for_v474.php +++ b/database/migrations/2018_04_29_174524_changes_for_v474.php @@ -37,6 +37,23 @@ class ChangesForV474 extends Migration */ public function down(): void { + Schema::table( + 'import_jobs', + function (Blueprint $table) { + + // cannot drop foreign keys in SQLite: + if ('sqlite' !== config('database.default')) { + $table->dropForeign('import_jobs_tag_id_foreign'); + } + + $table->dropColumn('provider'); + $table->dropColumn('stage'); + $table->dropColumn('transactions'); + $table->dropColumn('errors'); + $table->dropColumn('tag_id'); + + } + ); } /** diff --git a/database/migrations/2018_09_05_195147_changes_for_v477.php b/database/migrations/2018_09_05_195147_changes_for_v477.php index d155d5694a..6aae743150 100644 --- a/database/migrations/2018_09_05_195147_changes_for_v477.php +++ b/database/migrations/2018_09_05_195147_changes_for_v477.php @@ -38,7 +38,17 @@ class ChangesForV477 extends Migration */ public function down(): void { - // + Schema::table( + 'budget_limits', function (Blueprint $table) { + + // cannot drop foreign keys in SQLite: + if ('sqlite' !== config('database.default')) { + $table->dropForeign('budget_limits_transaction_currency_id_foreign'); + } + + $table->dropColumn(['transaction_currency_id']); + } + ); } /** diff --git a/database/migrations/2018_11_06_172532_changes_for_v479.php b/database/migrations/2018_11_06_172532_changes_for_v479.php index 2f79e4d015..9846f38f0a 100644 --- a/database/migrations/2018_11_06_172532_changes_for_v479.php +++ b/database/migrations/2018_11_06_172532_changes_for_v479.php @@ -36,7 +36,11 @@ class ChangesForV479 extends Migration */ public function down() { - // + Schema::table( + 'transaction_currencies', function (Blueprint $table) { + $table->dropColumn(['enabled']); + } + ); } /** diff --git a/public/v1/js/ff/search/index.js b/public/v1/js/ff/search/index.js index c7ccc645ef..c178767735 100644 --- a/public/v1/js/ff/search/index.js +++ b/public/v1/js/ff/search/index.js @@ -39,8 +39,6 @@ function searchFailure() { function presentSearchResults(data) { $('.search_ongoing').hide(); - $('p.search_count').show(); - $('span.search_count').text(data.count); $('.search_box').find('.overlay').remove(); $('.search_results').html(data.html).show(); diff --git a/resources/lang/de_DE/firefly.php b/resources/lang/de_DE/firefly.php index ccad7ca749..c95a840821 100644 --- a/resources/lang/de_DE/firefly.php +++ b/resources/lang/de_DE/firefly.php @@ -217,7 +217,27 @@ return [ // search 'search' => 'Suche', 'search_query' => 'Abfrage', - 'search_found_transactions' => 'Anzahl der gefundenen Buchungen:', + 'search_found_transactions' => 'Firefly III found :count transaction(s) in :time seconds.', + 'search_for_query' => 'Firefly III is searching for transactions with all of these words in them: :query', + 'search_modifier_amount_is' => 'Amount is exactly :value', + 'search_modifier_amount' => 'Amount is exactly :value', + 'search_modifier_amount_max' => 'Amount is at most :value', + 'search_modifier_amount_min' => 'Amount is at least :value', + 'search_modifier_amount_less' => 'Amount is less than :value', + 'search_modifier_amount_more' => 'Amount is more than :value', + 'search_modifier_source' => 'Source account is :value', + 'search_modifier_destination' => 'Destination account is :value', + 'search_modifier_category' => 'Category is :value', + 'search_modifier_budget' => 'Budget is :value', + 'search_modifier_bill' => 'Bill is :value', + 'search_modifier_type' => 'Transaction type is :value', + 'search_modifier_date' => 'Transaction date is :value', + 'search_modifier_date_before' => 'Transaction date is before :value', + 'search_modifier_date_after' => 'Transaction date is after :value', + 'search_modifier_on' => 'Transaction date is :value', + 'search_modifier_before' => 'Transaction date is before :value', + 'search_modifier_after' => 'Transaction date is after :value', + 'modifiers_applies_are' => 'The following modifiers are applied to the search as well:', 'general_search_error' => 'Bei der Suche ist ein Fehler aufgetreten. Bitte überprüfen Sie die Protokolldateien für weitere Informationen.', 'search_box' => 'Suche', 'search_box_intro' => 'Willkommen zur Suchfunktion von Firefly III. Geben Sie Ihre Suchanfrage in das Feld ein. Stellen Sie sicher, dass Sie sich die Hilfe ansehen, da die Suche ziemlich umfangreich ist.', diff --git a/resources/lang/en_US/firefly.php b/resources/lang/en_US/firefly.php index 7146a141d9..2d4da6337d 100644 --- a/resources/lang/en_US/firefly.php +++ b/resources/lang/en_US/firefly.php @@ -217,7 +217,27 @@ return [ // search 'search' => 'Search', 'search_query' => 'Query', - 'search_found_transactions' => 'Number of transactions found:', + 'search_found_transactions' => 'Firefly III found :count transaction(s) in :time seconds.', + 'search_for_query' => 'Firefly III is searching for transactions with all of these words in them: :query', + 'search_modifier_amount_is' => 'Amount is exactly :value', + 'search_modifier_amount' => 'Amount is exactly :value', + 'search_modifier_amount_max' => 'Amount is at most :value', + 'search_modifier_amount_min' => 'Amount is at least :value', + 'search_modifier_amount_less' => 'Amount is less than :value', + 'search_modifier_amount_more' => 'Amount is more than :value', + 'search_modifier_source' => 'Source account is :value', + 'search_modifier_destination' => 'Destination account is :value', + 'search_modifier_category' => 'Category is :value', + 'search_modifier_budget' => 'Budget is :value', + 'search_modifier_bill' => 'Bill is :value', + 'search_modifier_type' => 'Transaction type is :value', + 'search_modifier_date' => 'Transaction date is :value', + 'search_modifier_date_before' => 'Transaction date is before :value', + 'search_modifier_date_after' => 'Transaction date is after :value', + 'search_modifier_on' => 'Transaction date is :value', + 'search_modifier_before' => 'Transaction date is before :value', + 'search_modifier_after' => 'Transaction date is after :value', + 'modifiers_applies_are' => 'The following modifiers are applied to the search as well:', 'general_search_error' => 'An error occured while searching. Please check the log files for more information.', 'search_box' => 'Search', 'search_box_intro' => 'Welcome to the search function of Firefly III. Enter your search query in the box. Make sure you check out the help file because the search is pretty advanced.', diff --git a/resources/lang/es_ES/demo.php b/resources/lang/es_ES/demo.php index 82d6bb7fc4..15c3e90766 100644 --- a/resources/lang/es_ES/demo.php +++ b/resources/lang/es_ES/demo.php @@ -26,7 +26,7 @@ return [ 'no_demo_text' => 'Lamentablemente no hay textos de ayuda para esta página.', 'see_help_icon' => 'Sin embargo, el icono en la esquina superior derecha puede tener más información.', 'index' => '¡Bienvenido a Firefly III! En esta página tendrá una vista rápida de sus finanzas. Para más información, mire sus cuentas → Cuentas de activos y, por supuesto, las páginas de presupuestos e Informes. O simplemente investigue la aplicación por su cuenta.', - 'accounts-index' => 'Asset accounts are your personal bank accounts. Expense accounts are the accounts you spend money at, such as stores and friends. Revenue accounts are accounts you receive money from, such as your job, the government or other sources of income. Liabilities are your debts and loans such as old credit card debts or student loans. On this page you can edit or remove them.', + 'accounts-index' => 'Las cuentas de activos son tus cuentas bancarias personales. Las cuentas de gastos son las que gastas dinero, como tiendas y amigos. Las cuentas de ingresos son cuentas de las que recibes dinero, como tu trabajo, el gobierno u otras fuentes de ingresos. Los pasivos son tus deudas y préstamos como deudas de tarjetas de crédito antiguas o préstamos estudiantiles. En esta página puedes editarlas o eliminarlas.', 'budgets-index' => 'Esta página le muestra una visión general de sus presupuestos. La barra superior muestra la cantidad que está disponible para ser presupuestada. Esto se puede personalizar para cualquier período haciendo clic en la cantidad a la derecha. La cantidad que ha gastado hasta ahora se muestra en la barra de abajo. Debajo están los gastos por presupuesto y lo que ha presupuestado para ellos.', 'reports-index-start' => 'Firefly III da soporte a un buen numero de tipos de informes. Lea sobre ellos haciendo clic en el icono en la esquina superior derecha.', 'reports-index-examples' => 'Asegúrese de revisar estos ejemplos: un resumen financiero mensual, un resumen financiero anual y una vista general del presupuesto.', @@ -34,5 +34,5 @@ return [ 'transactions-index' => 'Estos gastos, depósitos y transferencias no son particularmente imaginativos. Se han generado automáticamente.', 'piggy-banks-index' => 'Como puede ver, hay tres huchas. Utilice los botones más y menos para influir en la cantidad de dinero en cada hucha. Haga clic en el nombre de la hucha para ver la administración de cada una.', 'import-index' => 'Cualquier archivo CSV se puede importar en Firefly III. También soporta la importación de datos desde bunq y Spectre. Otros bancos y agregadores financieros se implementarán en el futuro. Sin embargo, como usuario de la demo, solo puede ver el "falso"-proveedor en acción. Generará algunas transacciones aleatorias para mostrarle cómo funciona el proceso.', - 'profile-index' => 'Keep in mind that the demo site resets every four hours. Your access may be revoked at any time. This happens automatically and is not a bug.', + 'profile-index' => 'Tenga en cuenta que el sitio de demostración se restablece cada cuatro horas. Su acceso puede ser revocado en cualquier momento. Esto ocurre automáticamente y no es un error.', ]; diff --git a/resources/lang/es_ES/firefly.php b/resources/lang/es_ES/firefly.php index c8c1fe24bd..81a8e5aaa1 100644 --- a/resources/lang/es_ES/firefly.php +++ b/resources/lang/es_ES/firefly.php @@ -29,7 +29,7 @@ return [ 'edit' => 'Editar', 'delete' => 'Eliminar', 'split' => 'Separar', - 'clone' => 'Clonar', + 'clone' => 'Duplicar', 'last_seven_days' => 'Últimos siete días', 'last_thirty_days' => 'Últimos treinta días', 'welcomeBack' => '¿Qué está pasando?', @@ -41,7 +41,7 @@ return [ 'cancel' => 'Cancelar', 'from' => 'Desde', 'to' => 'Hasta', - 'structure' => 'Structure', + 'structure' => 'Estructura', 'help_translating' => 'Este texto de ayuda no está disponible en tu idioma. ¿Nos ayudaría a traducir?', 'showEverything' => 'Mostrar todo', 'never' => 'Nunca', @@ -59,7 +59,7 @@ return [ 'go_to_bills' => 'Ir a tus cuentas', 'go_to_expense_accounts' => 'Ver tus cuentas de gastos', 'go_to_revenue_accounts' => 'Ver tus cuentas de ingresos', - 'go_to_piggies' => 'Ir a tu alcancía', + 'go_to_piggies' => 'Ir a tu hucha', 'new_deposit' => 'Nuevo depósito', 'new_transfer' => 'Nueva transferencia', 'new_transfers' => 'Nueva transferencia', @@ -114,7 +114,7 @@ return [ 'cannot_redirect_to_account' => 'Firefly III no puede redirigirlo a la pagina correcta. Disculpas.', 'sum_of_expenses' => 'Total gastos', 'sum_of_income' => 'Total ingresos', - 'liabilities' => 'Liabilities', + 'liabilities' => 'Pasivos', 'spent_in_specific_budget' => 'Gastado en el presupuesto ":budget"', 'sum_of_expenses_in_budget' => 'Gastar todo en el presupuesto ":budget"', 'left_in_budget_limit' => 'Saldo para gastar acorde con el presupuesto', @@ -178,11 +178,11 @@ return [ 'button_reset_password' => 'Reestablecer contraseña', 'reset_button' => 'Restablecer', 'want_to_login' => 'Quiero entrar al sistema', - 'login_page_title' => 'Login to Firefly III', - 'register_page_title' => 'Register at Firefly III', - 'forgot_pw_page_title' => 'Forgot your password for Firefly III', - 'reset_pw_page_title' => 'Reset your password for Firefly III', - 'cannot_reset_demo_user' => 'You cannot reset the password of the demo user.', + 'login_page_title' => 'Iniciar sesión en Firefly III', + 'register_page_title' => 'Registrarse en Firefly III', + 'forgot_pw_page_title' => 'Olvidó su contraseña para Firefly III', + 'reset_pw_page_title' => 'Restablecer contraseña para Firefly III', + 'cannot_reset_demo_user' => 'No puedes restablecer la contraseña del usuario demo.', 'button_register' => 'Registrarse', 'authorization' => 'Autorización', 'active_bills_only' => 'sólo facturas activas', @@ -217,7 +217,27 @@ return [ // search 'search' => 'Buscar', 'search_query' => 'Consulta', - 'search_found_transactions' => 'Transacciones encontradas:', + 'search_found_transactions' => 'Firefly III found :count transaction(s) in :time seconds.', + 'search_for_query' => 'Firefly III is searching for transactions with all of these words in them: :query', + 'search_modifier_amount_is' => 'Amount is exactly :value', + 'search_modifier_amount' => 'Amount is exactly :value', + 'search_modifier_amount_max' => 'Amount is at most :value', + 'search_modifier_amount_min' => 'Amount is at least :value', + 'search_modifier_amount_less' => 'Amount is less than :value', + 'search_modifier_amount_more' => 'Amount is more than :value', + 'search_modifier_source' => 'Source account is :value', + 'search_modifier_destination' => 'Destination account is :value', + 'search_modifier_category' => 'Category is :value', + 'search_modifier_budget' => 'Budget is :value', + 'search_modifier_bill' => 'Bill is :value', + 'search_modifier_type' => 'Transaction type is :value', + 'search_modifier_date' => 'Transaction date is :value', + 'search_modifier_date_before' => 'Transaction date is before :value', + 'search_modifier_date_after' => 'Transaction date is after :value', + 'search_modifier_on' => 'Transaction date is :value', + 'search_modifier_before' => 'Transaction date is before :value', + 'search_modifier_after' => 'Transaction date is after :value', + 'modifiers_applies_are' => 'The following modifiers are applied to the search as well:', 'general_search_error' => 'Se ha producido un error durante la búsqueda. Por favor, compruebe los archivos de registro para obtener más información.', 'search_box' => 'Buscar', 'search_box_intro' => 'Bienvenido a la función de búsqueda de Firefly III. Introduce tu consulta de búsqueda en el cuadro. Asegúrate de revisar el archivo de ayuda porque el buscador es bastante avanzado.', @@ -273,7 +293,7 @@ return [ 'rule_priority_up' => 'Dar una regla mas prioritaria', 'rule_priority_down' => 'Dar una regla menos prioritaria', 'make_new_rule_group' => 'Hacer un nuevo grupo de reglas', - 'store_new_rule_group' => 'Almacenar nuevo grupo de reglas', + 'store_new_rule_group' => 'Crear grupo de reglas', 'created_new_rule_group' => 'Nuevo grupo de reglas ":title" guardado!', 'updated_rule_group' => 'Grupo de reglas actualizado exitosamente ":title".', 'edit_rule_group' => 'Editar grupo de reglas ":title"', @@ -294,7 +314,7 @@ return [ 'rule_help_active' => 'Las reglas inactivas nunca se ejecutan.', 'stored_new_rule' => 'Guardar la nueva regla con titulo ":title"', 'deleted_rule' => 'Regla eliminada con titulo ":title"', - 'store_new_rule' => 'Almacenar nueva regla', + 'store_new_rule' => 'Crear regla', 'updated_rule' => 'Regla eliminada con titulo ":title"', 'default_rule_group_name' => 'Reglaspredeterminada', 'default_rule_group_description' => 'Todas las reglas que no pertenecen a ningún grupo.', @@ -314,7 +334,7 @@ return [ 'add_rule_action' => 'Añadir nueva acción', 'edit_rule' => 'Editar regla ":title"', 'delete_rule' => 'Eliminar regla ":title"', - 'update_rule' => 'Regla de actualización', + 'update_rule' => 'Actualizar regla', 'test_rule_triggers' => 'Ver transacciones que coinciden', 'warning_transaction_subset' => 'Por razones de actuación esta lista esta limitada a :max_num_transactions y puede solo mostrar un subconjunto de transacciones coincidentes', 'warning_no_matching_transactions' => 'No se encontraron transacciones que coinciden. por favor tome nota por motivos de rendimiento, solo el ultimo :num_transactions transacciones han sido chequeadas.', @@ -355,7 +375,7 @@ return [ 'rule_trigger_amount_exactly_choice' => 'Cantidad es..', 'rule_trigger_amount_exactly' => 'Cantidad es :trigger_value', 'rule_trigger_amount_more_choice' => 'Cantidad es mas de..', - 'rule_trigger_amount_more' => 'El monto es mas que :trigger_value', + 'rule_trigger_amount_more' => 'Cantidad es más de :trigger_value', 'rule_trigger_description_starts_choice' => 'Descripción comienza con..', 'rule_trigger_description_starts' => 'La descripción comienza con ":trigger_value"', 'rule_trigger_description_ends_choice' => 'Descripción termina con..', @@ -451,7 +471,7 @@ return [ 'new_rule_for_bill_description' => 'Esta regla marca las transacciones para la cuenta ":name".', // tags - 'store_new_tag' => 'Almacenar nueva etiqueta', + 'store_new_tag' => 'Crear etiqueta', 'update_tag' => 'Actualizar etiqueta', 'no_location_set' => 'Ubicación no establecida.', 'meta_data' => 'Meta Datos', @@ -459,7 +479,7 @@ return [ 'without_date' => 'Sin fecha', 'result' => 'Resultado', 'sums_apply_to_range' => 'Todas las sumas aplican al rango seleccionado', - 'mapbox_api_key' => 'To use map, get an API key from Mapbox. Open your .env file and enter this code after MAPBOX_API_KEY=.', + 'mapbox_api_key' => 'Para usar el mapa, obtenga una clave API de MapboxAbra su.env y introduzca este código después de MAPBOX_API_KEY=.', 'press_tag_location' => 'Haga clic o pulse de forma prolongada para definir la ubicación de la etiqueta.', 'clear_location' => 'Eliminar ubicación', @@ -541,13 +561,13 @@ return [ 'invalid_password' => 'Contraseña invalida!', 'what_is_pw_security' => '¿Que es "verificar la seguridad de contraseña?', 'secure_pw_title' => 'Como escoger una contraseña segura', - 'secure_pw_history' => 'Not a week goes by that you read in the news about a site losing the passwords of its users. Hackers and thieves use these passwords to try to steal your private information. This information is valuable.', - 'secure_pw_ff' => 'Do you use the same password all over the internet? If one site loses your password, hackers have access to all your data. Firefly III relies on you to choose a strong and unique password to protect your financial records.', - 'secure_pw_check_box' => 'To help you do that Firefly III can check if the password you want to use has been stolen in the past. If this is the case, Firefly III advises you NOT to use that password.', - 'secure_pw_working_title' => 'How does it work?', - 'secure_pw_working' => 'By checking the box, Firefly III will send the first five characters of the SHA1 hash of your password to the website of Troy Hunt to see if it is on the list. This will stop you from using unsafe passwords as is recommended in the latest NIST Special Publication on this subject.', + 'secure_pw_history' => 'Cada semana leemos en las noticias sobre un sitio que pierde las contraseñas de sus usuarios. Hackers y ladrones utilizan estas contraseñas para intentar robar tu información privada. Esta información es valiosa.', + 'secure_pw_ff' => '¿Utiliza la misma contraseña a través de Internet? Si un sitio pierde su contraseña, los hackers tienen acceso a todos sus datos. Firefly III depende de usted para elegir una contraseña fuerte y única para proteger sus registros financieros.', + 'secure_pw_check_box' => 'Para ayudarte a hacer eso Firefly III puede comprobar si la contraseña que quieres usar ha sido robada en el pasado. Si este es el caso, Firefly III te aconseja NO usar esa contraseña.', + 'secure_pw_working_title' => '¿Cómo funciona?', + 'secure_pw_working' => 'Marcando la casilla, Firefly III enviará los cinco primeros caracteres del hash SHA1 de su contraseña al sitio web de Troy Hunt para ver si esta en la lista. Esto le impedirá a usted usar contraseñas inseguras como se recomienda en la última Publicación Especial de NISH sobre este tema.', 'secure_pw_should' => '¿Debo chequear la casilla?', - 'secure_pw_long_password' => 'Yes. Always verify your password is safe.', + 'secure_pw_long_password' => 'Sí. Verificar siempre que su contraseña es segura.', 'command_line_token' => 'Token de linea de comando', 'explain_command_line_token' => 'Necesita este token para realizar opciones de línea de comando, como importar o exportar datos. Sin él, dichos comandos confidenciales no funcionarán. No compartas tu token de línea de comando. Nadie te lo pedirá, ni siquiera a nosotros. Si crees que lo has perdido, o si estás paranoico, regenera tu token pulsando el botón.', 'regenerate_command_line_token' => 'Regenerar token de línea de comando', @@ -557,8 +577,8 @@ return [ 'email_changed_logout' => 'Hasta que usted verifique su dirección de correo electrónico, usted no puede iniciar sesión.', 'login_with_new_email' => 'Usted puede ahora iniciar sesión con su nueva dirección de correo electrónico.', 'login_with_old_email' => 'Usted puede ahora iniciar sesión con su vieja dirección de correo electrónico otra vez.', - 'login_provider_local_only' => 'This action is not available when authenticating through ":login_provider".', - 'delete_local_info_only' => 'Because you authenticate through ":login_provider", this will only delete local Firefly III information.', + 'login_provider_local_only' => 'Esta acción no está disponible cuando se identifica a través de ":login_provider".', + 'delete_local_info_only' => 'Debido a que se identificado a través de ":login_provider", sólo se eliminará la información local de Firefly III.', // attachments 'nr_of_attachments' => 'Un archivo adjunto:count archivos adjuntos', @@ -626,25 +646,25 @@ return [ // currencies: 'create_currency' => 'Crear nueva moneda', - 'store_currency' => 'Almacenar nueva moneda', + 'store_currency' => 'Crear moneda', 'update_currency' => 'Actualizar moneda', 'new_default_currency' => ':name es ahora moneda por defecto.', 'cannot_delete_currency' => 'No puede eliminar :name porque todavía esta en uso.', - 'cannot_disable_currency' => 'Cannot disable :name because it is still in use.', + 'cannot_disable_currency' => 'No se puede desactivar :name porque todavía está en uso.', 'deleted_currency' => 'Moneda :name eliminada', 'created_currency' => 'Moneda :name creada', - 'could_not_store_currency' => 'No se puede almacenar la nueva moneda.', + 'could_not_store_currency' => 'No se puede crear la nueva moneda.', 'updated_currency' => 'Moneda :name actualizada', 'ask_site_owner' => 'Por favor pregunte :owner por agregar,elimine o edite monedas.', 'currencies_intro' => 'Firefly III respalda varias monedas que usted puede establecer y habilitar aquí.', - 'make_default_currency' => 'Make default', - 'default_currency' => 'en mora', - 'currency_is_disabled' => 'Disabled', - 'enable_currency' => 'Enable', - 'disable_currency' => 'Disable', - 'currencies_default_disabled' => 'Most of these currencies are disabled by default. To use them, you must enable them first.', - 'currency_is_now_enabled' => 'Currency ":name" has been enabled', - 'currency_is_now_disabled' => 'Currency ":name" has been disabled', + 'make_default_currency' => 'Establecer por defecto', + 'default_currency' => 'por defecto', + 'currency_is_disabled' => 'Deshabilitado', + 'enable_currency' => 'Activar', + 'disable_currency' => 'Desactivar', + 'currencies_default_disabled' => 'La mayoría de estas monedas están desactivadas por defecto. Para usarlas, debes activarlas primero.', + 'currency_is_now_enabled' => 'Moneda ":name" ha sido activada', + 'currency_is_now_disabled' => 'Moneda ":name" ha sido desactivada', // forms: 'mandatoryFields' => 'Campos obligatorios', @@ -654,7 +674,7 @@ return [ // budgets: 'create_new_budget' => 'Crear un nuevo presupuesto', 'store_new_budget' => 'Almacene el nuevo presupuesto', - 'stored_new_budget' => 'Almacenar el nuevo presupuesto ":name"', + 'stored_new_budget' => 'Presupuesto ":name" creado', 'available_between' => 'Disponible entre :start y :end', 'transactionsWithoutBudget' => 'Gastos sin presupuesto', 'transactions_no_budget' => 'Gastos sin presupuesto entre :start y :end', @@ -666,12 +686,12 @@ return [ 'deleted_budget' => 'Presupuesto eliminado ":name"', 'edit_budget' => 'Editar presupuesto ":name"', 'updated_budget' => 'Presupuesto actualizado ":name"', - 'update_amount' => 'Actualizar monto', + 'update_amount' => 'Actualizar cantidad', 'update_budget' => 'Actualizar presupuesto', 'update_budget_amount_range' => 'Cantidad disponible (esperada) actualizada entre :start y :end', 'budget_period_navigator' => 'Periodo navegador', 'info_on_available_amount' => '¿ que tengo disponible?', - 'available_amount_indication' => 'Use estos montos para obtener una indicación de cual podría ser el presupuesto total.', + 'available_amount_indication' => 'Utilice estas cantidades para obtener una indicación de lo que podría ser su presupuesto total.', 'suggested' => 'Sugerido', 'average_between' => 'Promedio entre :start y :end', 'over_budget_warn' => ' Normalmente usas de tu presupuesto, cerca de :amount por día. Se trata de :over_amount por día.', @@ -691,12 +711,12 @@ return [ 'rescan_old' => 'Ejecutar las reglas de nuevo, en todas las transacciones', 'update_bill' => 'Actualizar factura', 'updated_bill' => 'Actualizar factura ":name"', - 'store_new_bill' => 'Almacenar nueva factura', - 'stored_new_bill' => 'Almacenar nueva factura ":name"', + 'store_new_bill' => 'Crear factura', + 'stored_new_bill' => 'Factura ":name" creada', 'cannot_scan_inactive_bill' => 'Las facturas inactivas no pueden ser escaneadas.', 'rescanned_bill' => 'Se reescaneó todo y se linkearon :total transaccion(es) a la cuenta.', - 'average_bill_amount_year' => 'Monto promedio de la factura (:year)', - 'average_bill_amount_overall' => 'Monto promedio de la factura (sobretodo)', + 'average_bill_amount_year' => 'Cantidad media de la factura (:year)', + 'average_bill_amount_overall' => 'Cantidad media de las facturas (total)', 'bill_is_active' => 'Bill esta activo', 'bill_expected_between' => 'Esperado entre :start y :end', 'bill_will_automatch' => 'Bill se vinculara automáticamente a transacciones coincidentes', @@ -710,9 +730,9 @@ return [ 'details_for_expense' => 'Detalles para la cuenta de gastos ":name"', 'details_for_revenue' => 'Detalles para la cuenta de ingresos ":name"', 'details_for_cash' => 'Detalle para la cuenta de efectivo ":name"', - 'store_new_asset_account' => 'Almacenar nueva cuenta de activos', - 'store_new_expense_account' => 'Almacenar cuenta nueva de gastos', - 'store_new_revenue_account' => 'Almacenar cuenta nueva de ingresos', + 'store_new_asset_account' => 'Crear cuenta de activos', + 'store_new_expense_account' => 'Crear cuenta de gastos', + 'store_new_revenue_account' => 'Crear cuenta de ingresos', 'edit_asset_account' => 'Editar cuenta de activos ":name"', 'edit_expense_account' => 'Editar cuenta de gastos ":name"', 'edit_revenue_account' => 'Editar cuenta de ganancias ":name"', @@ -741,7 +761,7 @@ return [ 'overview_of_reconcile_modal' => 'Resumen de reconciliación', 'delete_reconciliation' => 'Eliminar reconciliacion', 'update_reconciliation' => 'Actualizar reconciliacion', - 'amount_cannot_be_zero' => 'El monto no puede ser cero', + 'amount_cannot_be_zero' => 'La cantidad no puede ser cero', 'end_of_reconcile_period' => 'Fin del periodo de reconciliacion::period', 'start_of_reconcile_period' => 'Inicio de periodo de reconciliación::period', 'start_balance' => 'Balance inicial', @@ -765,13 +785,13 @@ return [ 'updated_account' => 'Cuenta actualizada ":name"', 'credit_card_options' => 'Opciones de tarjeta de crédito', 'no_transactions_account' => 'No hay transacciones ( en este periodo) para cuenta de activos ":name".', - 'no_transactions_period' => 'There are no transactions (in this period).', + 'no_transactions_period' => 'No hay transacciones (en este período).', 'no_data_for_chart' => 'No hay suficiente información (todavía) para generar este gráfico.', - 'select_at_least_one_account' => 'Please select at least one asset account', - 'select_at_least_one_category' => 'Please select at least one category', - 'select_at_least_one_budget' => 'Please select at least one budget', - 'select_at_least_one_tag' => 'Please select at least one tag', - 'select_at_least_one_expense' => 'Please select at least one combination of expense/revenue accounts. If you have none (the list is empty) this report is not available.', + 'select_at_least_one_account' => 'Por favor, seleccione al menos una cuenta', + 'select_at_least_one_category' => 'Por favor, seleccione al menos una categoría', + 'select_at_least_one_budget' => 'Por favor, seleccione al menos un presupuesto', + 'select_at_least_one_tag' => 'Por favor, seleccione al menos una etiqueta', + 'select_at_least_one_expense' => 'Por favor, seleccione al menos una combinación de cuentas de gastos/ingresos. Si no tiene ninguna (la lista está vacía) este informe no está disponible.', 'account_default_currency' => 'Esta será la moneda por defecto asociada a esta cuenta.', 'reconcile_has_more' => 'Su libro principal de Firefly III tiene mas dinero de lo que su banco afirma debería tener, Hay varias opciones. por favor elija que hacer. luego, presione "confirmar reconciliación".', 'reconcile_has_less' => 'Su libro principal de Firefly III tiene menos dinero de el que su banco dice que usted debería tener. hay varias opciones. Por favor elija que hacer, luego presione " Confirmar reconciliación".', @@ -794,7 +814,7 @@ return [ 'interest_calc_daily' => 'Por dia', 'interest_calc_monthly' => 'Por mes', 'interest_calc_yearly' => 'Por año', - 'initial_balance_account' => 'Initial balance account of :name', + 'initial_balance_account' => 'Balance inicial de la cuenta :name', // categories: 'new_category' => 'Nueva categoría', @@ -833,7 +853,7 @@ return [ 'reconcile_selected' => 'Reconciliar', 'mass_delete_journals' => 'Eliminar un numero de transacciones', 'mass_edit_journals' => 'Editar un numero de transacciones', - 'mass_bulk_journals' => 'Bulk editar un numero de transacciones', + 'mass_bulk_journals' => 'Editar múltiples transacciones', 'mass_bulk_journals_explain' => 'Si usted no desea cambiar sus transacciones a una mediante la función de edición masiva, usted puede actualizarlas de una sola vez. simplemente seleccione la categoría, las etiquetas o el presupuesto preferidos en los campos de abajo, y todas las transacciones de la tabla se actualizaran.', 'bulk_set_new_values' => 'Use las entradas abajo para establecer nuevos valores. Si usted los deja vacíos, serán vacíos para todos. también, tenga en cuenta que solo los retiros tendrán un presupuesto.', 'no_bulk_category' => 'No actualizar la categoria', @@ -848,7 +868,7 @@ return [ 'mass_edited_transactions_success' => 'Actualizado :amount transacción (es)', 'opt_group_' => '(Sin tipo de cuenta)', 'opt_group_no_account_type' => '(Sin tipo de cuenta)', - 'opt_group_defaultAsset' => 'Cuenta de ingresos por mora', + 'opt_group_defaultAsset' => 'Cuentas de activos por defecto', 'opt_group_savingAsset' => 'Cuenta de ahorros', 'opt_group_sharedAsset' => 'Cuenta de activos compartidas', 'opt_group_ccAsset' => 'Tarjetas de credito', @@ -859,8 +879,8 @@ return [ 'opt_group_l_Credit card' => 'Pasivo: Tarjeta de crédito', 'notes' => 'Notas', 'unknown_journal_error' => 'No se pudo guardar la transacción. Por favor, revise los archivos de registro.', - 'attachment_not_found' => 'This attachment could not be found.', - 'journal_link_bill' => 'This transaction is linked to bill :name. To remove the connection, uncheck the checkbox. Use rules to connect it to another bill.', + 'attachment_not_found' => 'No se pudo encontrar este adjunto.', + 'journal_link_bill' => 'Esta transacción está vinculada a la factura :name. Para eliminar la conexión, desmarca la casilla de verificación. Usa reglas para conectarla a otra factura.', // new user: 'welcome' => 'Bienvenido a Firefly III!', @@ -868,9 +888,8 @@ return [ 'submit_yes_really' => 'Enviar (Se lo que estoy haciendo)', 'getting_started' => 'Comenzando', 'to_get_started' => 'Es bueno ver que usted ha instalado con éxito Firefly III. Para comenzar con esta regla, por favor ingrese el nombre de su banco y el saldo de su cuenta de cheques principal. No se preocupe todavía si tiene varias cuentas. usted puede agregarlas luego. Es solo que Firefly III necesita algo para empezar.', - 'savings_balance_text' => 'Firefly II creara automáticamente una cuenta de ahorros para usted. Por - defecto. No abra dinero en su cuenta de ahorros. pero si le dice a Firefly III el saldo se almacenara como tal.', - 'finish_up_new_user' => 'Eso es! Usted puede continuar presionando. Usted sera llevado al indice de Firefly III.', + 'savings_balance_text' => 'Firefly II creará automáticamente una cuenta de ahorros. Por defecto, no habrá dinero en su cuenta de ahorros, pero si le dice a Firefly III el saldo se almacenará como tal.', + 'finish_up_new_user' => '¡Eso es! Puedes continuar presionando Enviar. Será llevado al inicio de Firefly III.', 'stored_new_accounts_new_user' => 'Hurra! Sus nuevas cuentas han sido almacenadas.', 'set_preferred_language' => 'Si prefiere usar Firefly II en otro lenguaje, por favor indíquelo aquí.', 'language' => 'Idioma', @@ -880,13 +899,13 @@ return [ // home page: 'yourAccounts' => 'Tus cuentas', - 'your_accounts' => 'Your account overview', - 'category_overview' => 'Category overview', - 'expense_overview' => 'Expense account overview', - 'revenue_overview' => 'Revenue account overview', + 'your_accounts' => 'Resumen de su cuenta', + 'category_overview' => 'Resumen de categorías', + 'expense_overview' => 'Resumen de la cuenta de gastos', + 'revenue_overview' => 'Resumen de la cuenta de ingresos', 'budgetsAndSpending' => 'Presupuestos y gastos', - 'budgets_and_spending' => 'Budgets and spending', - 'go_to_budget' => 'Go to budget "{budget}"', + 'budgets_and_spending' => 'Presupuestos y gastos', + 'go_to_budget' => 'Ir al presupuesto "{budget}"', 'savings' => 'Ahorros', 'newWithdrawal' => 'Nuevo gasto', 'newDeposit' => 'Nuevo deposito', @@ -904,10 +923,10 @@ return [ 'searchPlaceholder' => 'Buscar...', 'version' => 'Versión', 'dashboard' => 'Panel de control', - 'available_budget' => 'Available budget ({currency})', + 'available_budget' => 'Presupuesto disponible ({currency})', 'currencies' => 'Divisas', - 'activity' => 'Activity', - 'usage' => 'Usage', + 'activity' => 'Actividad', + 'usage' => 'Uso', 'accounts' => 'Cuentas', 'Asset account' => 'Cuenta de activos', 'Default account' => 'Cuenta de activos', @@ -926,11 +945,11 @@ return [ 'income' => 'Ingresos / salarios', 'transfers' => 'Transferencias', 'moneyManagement' => 'Gestión del dinero', - 'money_management' => 'Money management', - 'tools' => 'Tools', + 'money_management' => 'Gestión del dinero', + 'tools' => 'Herramientas', 'piggyBanks' => 'Huchas', - 'piggy_banks' => 'Piggy banks', - 'amount_x_of_y' => '{current} of {total}', + 'piggy_banks' => 'Huchas', + 'amount_x_of_y' => '{current} de {total}', 'bills' => 'Facturas', 'withdrawal' => 'Retiro', 'opening_balance' => 'Saldo inicial', @@ -954,8 +973,8 @@ return [ 'debt_start_date' => 'Fecha de inicio de deuda', 'debt_start_amount' => 'Cantidad inicial de la deuda', 'debt_start_amount_help' => 'Introduce la cantidad original de este pasivo como un número positivo. También puede ingresar la cantidad actual. Asegúrese de editar la fecha de abajo para que coincida.', - 'store_new_liabilities_account' => 'Store new liability', - 'edit_liabilities_account' => 'Edit liability ":name"', + 'store_new_liabilities_account' => 'Crear nuevo pasivo', + 'edit_liabilities_account' => 'Editar pasivo ":name"', // reports: 'report_default' => 'Reporte financiero por defecto entre :start y :end', @@ -965,11 +984,11 @@ return [ 'report_budget' => 'Reporte de presupuesto entre :start y :end', 'report_tag' => 'Reporte de etiqueta entre :start y :end', 'quick_link_reports' => 'Enlaces rápidos', - 'quick_link_examples' => 'These are just some example links to get you started. Check out the help pages under the (?)-button for information on all reports and the magic words you can use.', + 'quick_link_examples' => 'Estos son sólo algunos enlaces de ejemplo para empezar. Echa un vistazo a las páginas de ayuda bajo el botón (?)-para obtener información sobre todos los informes y las palabras mágicas que puedes usar.', 'quick_link_default_report' => 'Reporte financiero por defecto', 'quick_link_audit_report' => 'Resumen del historial de transacciones', 'report_this_month_quick' => 'Mes en curso, todas las cuentas', - 'report_last_month_quick' => 'Last month, all accounts', + 'report_last_month_quick' => 'Último mes, todas las cuentas', 'report_this_year_quick' => 'Año en curso, todas las cuentas', 'report_this_fiscal_year_quick' => 'Año fiscal en curso, todas las cuentas', 'report_all_time_quick' => 'Todo el tiempo, todas las cuentas', @@ -993,7 +1012,7 @@ return [ 'show_full_list' => 'Mostrar lista entera', 'show_only_top' => 'Mostrar solo tope :number', 'report_type' => 'Tipo de reporte', - 'report_type_default' => 'Reporte financiero por mora', + 'report_type_default' => 'Informe financiero predeterminado', 'report_type_audit' => 'Resumen del historial de transacciones (auditar)', 'report_type_category' => 'Reporte de categoría', 'report_type_budget' => 'Reporte de presupuesto', @@ -1057,7 +1076,7 @@ return [ 'select_expense_revenue' => 'Seleccione cuenta de gastos/ingresos', 'multi_currency_report_sum' => 'Como esta lista contiene cuentas con múltiples monedas, la(s) suma(s) que veas puede no tener sentido. El reporte siempre figurará en tu moneda predeterminada.', 'sum_in_default_currency' => 'La suma siempre estará en tu moneda predeterminada.', - 'net_filtered_prefs' => 'This chart will never include accounts that have the "Include in net worth"-option unchecked.', + 'net_filtered_prefs' => 'Este gráfico nunca incluirá cuentas que tengan la opción "Incluir en el valor neto" no marcada.', // charts: 'chart' => 'Grafico', @@ -1069,8 +1088,8 @@ return [ 'earned' => 'Ganado', 'overspent' => 'Sobrepasadas', 'left' => 'Izquierda', - 'max-amount' => 'Monto máximo', - 'min-amount' => 'Monto minimo', + 'max-amount' => 'Cantidad máxima', + 'min-amount' => 'Cantidad mínima', 'journal-amount' => 'Entrada actual de factura', 'name' => 'Nombre', 'date' => 'Fecha', @@ -1081,36 +1100,36 @@ return [ 'period' => 'Período', 'balance' => 'Balance', 'sum' => 'Suma', - 'summary' => 'Summary', + 'summary' => 'Resumen', 'average' => 'Promedio', 'balanceFor' => 'Saldo por :name', - 'no_tags_for_cloud' => 'No tags to generate cloud', - 'tag_cloud' => 'Tag cloud', + 'no_tags_for_cloud' => 'No hay etiquetas para generar la nube', + 'tag_cloud' => 'Nube de etiquetas', // piggy banks: - 'add_money_to_piggy' => 'Añadir dinero a la alcancía ":name"', - 'piggy_bank' => 'Alcancía', - 'new_piggy_bank' => 'Nueva alcancía', - 'store_piggy_bank' => 'Archivar nueva alcancía', - 'stored_piggy_bank' => 'Archivar nueva alcancía ":name"', + 'add_money_to_piggy' => 'Añadir dinero a la hucha ":name"', + 'piggy_bank' => 'Hucha', + 'new_piggy_bank' => 'Nueva hucha', + 'store_piggy_bank' => 'Crear hucha', + 'stored_piggy_bank' => 'Crear hucha ":name"', 'account_status' => 'Estado de cuenta', 'left_for_piggy_banks' => 'Apartado para las huchas', 'sum_of_piggy_banks' => 'Total de huchas', 'saved_so_far' => 'Guardado hasta el momento', 'left_to_save' => 'Saldo para guardar', - 'suggested_amount' => 'Sugerir monto mensual para guardar', - 'add_money_to_piggy_title' => 'Añadir dinero a la alcancía ":name"', - 'remove_money_from_piggy_title' => 'Quitar dinero de la alcancía ":name"', + 'suggested_amount' => 'Cantidad mensual sugerida para ahorrar', + 'add_money_to_piggy_title' => 'Añadir dinero a la hucha ":name"', + 'remove_money_from_piggy_title' => 'Quitar dinero de la hucha ":name"', 'add' => 'Añadir', - 'no_money_for_piggy' => 'Usted no tiene dinero para colocar en esta alcancía.', + 'no_money_for_piggy' => 'Usted no tiene dinero para añadir a esta hucha.', 'suggested_savings_per_month' => 'Sugerido por mes', 'remove' => 'Eliminar', 'max_amount_add' => 'La cantidad máxima que usted puede agregar es', 'max_amount_remove' => 'La cantidad máxima que usted puede retirar es', 'update_piggy_button' => 'Actualizar alcancia', - 'update_piggy_title' => 'Actualizar alcancía ":name"', - 'updated_piggy_bank' => 'Actualizar alcancía ":name"', + 'update_piggy_title' => 'Actualizar hucha ":name"', + 'updated_piggy_bank' => 'Hucha ":name" actualizada', 'details' => 'Detalles', 'events' => 'Eventos', 'target_amount' => 'Cantidad objetivo', @@ -1119,10 +1138,10 @@ return [ 'target_date' => 'Fecha objetivo', 'no_target_date' => 'Sin fecha de objetivo', 'table' => 'Mesa', - 'delete_piggy_bank' => 'Eliminar alcancía ":name"', + 'delete_piggy_bank' => 'Eliminar hucha ":name"', 'cannot_add_amount_piggy' => 'No se pudo agregar :amount a ":name.".', 'cannot_remove_from_piggy' => 'No se pudo eliminar :amount de :name.', - 'deleted_piggy_bank' => 'Eliminar alcancía ":name"', + 'deleted_piggy_bank' => 'Hucha ":name" eliminada', 'added_amount_to_piggy' => 'Agregado :amount a ":name"', 'removed_amount_from_piggy' => 'Eliminado :amount de :name', @@ -1136,7 +1155,7 @@ return [ 'transaction_journal_information' => 'Información de transacción', 'transaction_journal_meta' => 'Información Meta', - 'total_amount' => 'Monto total', + 'total_amount' => 'Cantidad total', 'number_of_decimals' => 'Número de decimales', // administration @@ -1172,14 +1191,14 @@ return [ 'delete_user' => 'Eliminar usuario :email', 'user_deleted' => 'El usuario ha sido eliminado', 'send_test_email' => 'Enviar mensaje de correo electrónico de prueba', - 'send_test_email_text' => 'Para ver si su instalación es capaz de enviar correos electrónicos, presione este botón.Usted no vera un error aquí ( si hay)los archivos de registro reflejaran cualquier error . Usted puede presionar este botón tantas veces como lo desee. No hay control de spam. el mensaje sera enviado a :emaily llegara en breve.', + 'send_test_email_text' => 'Para ver si su instalación es capaz de enviar correos electrónicos, presione este botón. Usted no verá ningún error aquí (si los hubiera) los archivos de registro mostrarán cualquier error. Usted puede presionar este botón tantas veces como lo desee. No hay control de spam. El mensaje será enviado a :emaily debería llegar en breve.', 'send_message' => 'Enviar mensaje', 'send_test_triggered' => 'La prueba fue disparada. Chequee su bandeja de entrada y archivos de registro.', // links 'journal_link_configuration' => 'Configuración de enlaces de transacción', 'create_new_link_type' => 'Crear un nuevo tipo de enlace', - 'store_new_link_type' => 'Almacenar nuevo tipo de enlace', + 'store_new_link_type' => 'Crear tipo de enlace', 'update_link_type' => 'Actualizar tipo de enlace', 'edit_link_type' => 'Editar tipo de enlace ":name"', 'updated_link_type' => 'Actualizar tipo de enlace ":name"', @@ -1192,8 +1211,8 @@ return [ 'link_type_help_outward' => 'Ie."esta duplicado por"', 'save_connections_by_moving' => 'Guarde el enlace entre estas transacción (es) moviendolas a otro tipo de enlace:', 'do_not_save_connection' => '(no guarde la conexión)', - 'link_transaction' => 'Transacción de enlace', - 'link_to_other_transaction' => 'Enlace de transacción a otra transacción', + 'link_transaction' => 'Enlazar transacción', + 'link_to_other_transaction' => 'Enlazar esta transacción con otra', 'select_transaction_to_link' => 'Seleccione una transacción para enlazar esta transacción a', 'this_transaction' => 'Esta transacción', 'transaction' => 'Transaccion', @@ -1220,7 +1239,7 @@ return [ 'Reimbursement_name' => 'Reembolso', 'Related_name' => 'Relacionado', 'relates to_inward' => 'relacionado con', - 'is (partially) refunded by_inward' => 'es (parcialmente) es devuelto por', + 'is (partially) refunded by_inward' => 'es (parcialmente) devuelto por', 'is (partially) paid for by_inward' => 'es(parcialmente) pagado por', 'is (partially) reimbursed by_inward' => 'es(parcialmente) reembolsado por', 'inward_transaction' => 'Transacción interna', @@ -1267,7 +1286,7 @@ return [ 'no_accounts_imperative_revenue' => 'Las cuentas de ganancias se crean automáticamente cuando usted crea transacciones, pero usted puede crear una manualmente también, si usted quiere. vamos a crear una ahora:', 'no_accounts_create_revenue' => 'Crear una cuenta de ingresos', 'no_accounts_title_liabilities' => '¡Vamos a crear un pasivo!', - 'no_accounts_intro_liabilities' => 'You have no liabilities yet. Liabilities are the accounts that register your (student) loans and other debts.', + 'no_accounts_intro_liabilities' => 'Todavía no tienes pasivos. Los pasivos son las cuentas que registran sus préstamos y otras deudas.', 'no_accounts_imperative_liabilities' => 'No necesita usar esta función pero, puede ser muy útil si desea hacer un seguimiento de estas cosas.', 'no_accounts_create_liabilities' => 'Crear un pasivo', 'no_budgets_title_default' => 'Vamos a crear un presupuesto', @@ -1294,10 +1313,10 @@ return [ 'no_transactions_intro_transfers' => 'Usted no tiene transferencias aun. Cuando usted mueve dinero entre cuentas de activos, se registra como una transferencia.', 'no_transactions_imperative_transfers' => '¿Has movido algo de dinero? Entonces usted debería escribirlo:', 'no_transactions_create_transfers' => 'Crear una transferencia', - 'no_piggies_title_default' => '¡Vamos a crear una alcancía!', + 'no_piggies_title_default' => '¡Vamos a crear una hucha!', 'no_piggies_intro_default' => 'Aún no tienes huchas. Puedes crear huchas para dividir tus ahorros y hacer un seguimiento de para qué estás ahorrando.', - 'no_piggies_imperative_default' => '¿Usted tiene cosas para la cual usted esta ahorrando dinero? Cree una alcancía y haga seguimiento:', - 'no_piggies_create_default' => 'Crear una nueva alcancía', + 'no_piggies_imperative_default' => '¿Usted tiene cosas para las cuales está ahorrando dinero? Cree una hucha y haga su seguimiento:', + 'no_piggies_create_default' => 'Crear una nueva hucha', 'no_bills_title_default' => '¡Vamos a crear una factura!', 'no_bills_intro_default' => 'Usted no tiene facturas aun. Usted puede crear facturas para hacer un seguimiento de los gastos regulares, como su alquiler o el seguro.', 'no_bills_imperative_default' => '¿Tienes facturas periódicas? Crea una factura y haz un seguimiento de tus pagos:', @@ -1305,7 +1324,7 @@ return [ // recurring transactions 'recurrences' => 'Transacciones Recurrentes', - 'recurring_calendar_view' => 'Calendar', + 'recurring_calendar_view' => 'Calendario', 'no_recurring_title_default' => 'Vamos a crear una transacción recurrente!', 'no_recurring_intro_default' => 'Usted no tiene transacciones recurrentes aún. Puede usar esto para hacer que Firefly III cree transacciones por usted.', 'no_recurring_imperative_default' => 'Esta es una característica bastante avanzada pero, puede ser extremadamente útil. Asegúrese de haber leído la documentación (?- Icono en la esquina derecha) antes de continuar.', @@ -1313,18 +1332,18 @@ return [ 'make_new_recurring' => 'Crear una transacción recurrente', 'recurring_daily' => 'Diario', 'recurring_weekly' => 'Cada semana los :weekday', - 'recurring_monthly' => 'Todos los meses el día: :dayOfMonth(st/nd/rd/th)', - 'recurring_ndom' => 'Todos los meses el día: :dayOfMonth(st/nd/rd/th) :weekday', + 'recurring_monthly' => 'Todos los meses, el :dayOfMonthº día', + 'recurring_ndom' => 'Todos los meses, el :dayOfMonthº :weekday', 'recurring_yearly' => 'Cada año en :date', 'overview_for_recurrence' => 'Resumen de transacción recurrente ":title"', 'warning_duplicates_repetitions' => 'En algunas ocasiones, las fechas aparecen duplicadas en esta lista. Esto puede ocurrir porque múltiples repeticiones chocan. Firefly III siempre generará una transacción por día.', 'created_transactions' => 'Transacciones relacionadas', - 'expected_withdrawals' => 'Expected withdrawals', - 'expected_deposits' => 'Expected deposits', - 'expected_transfers' => 'Expected transfers', - 'created_withdrawals' => 'Created withdrawals', - 'created_deposits' => 'Created deposits', - 'created_transfers' => 'Created transfers', + 'expected_withdrawals' => 'Extractos previstos', + 'expected_deposits' => 'Ingresos previstos', + 'expected_transfers' => 'Transferencias previstas', + 'created_withdrawals' => 'Extractos creadas', + 'created_deposits' => 'Depósitos creados', + 'created_transfers' => 'Transferencias creadas', 'created_from_recurrence' => 'Creado a partir de transacción recurrente ":title" (#:id)', 'recurring_never_cron' => 'Al parecer, el cron job necesario para realizar las transacciones recurrentes nunca se ejecutó. Esto es normal por supuesto, cuando acabas de instalar Firefly III pero, es algo que deberías configurar lo antes posible. Por favor, revisa las páginas de ayuda usando el ícono-(?) en la esquina derecha de la página.', 'recurring_cron_long_ago' => 'Aparentemente han pasado mas de 36 horas desde que el cron job para dar soporte a las transacciones recurrentes se ha disparado por última vez. Está usted seguro que lo ha configurado correctamente? Por favor, revise las páginas de ayuda usando el ícono-(?) en la esquina derecha de la página.', @@ -1349,7 +1368,7 @@ return [ 'repeat_times' => 'Repetir un número de veces', 'recurring_skips_one' => 'Intercalado', 'recurring_skips_more' => 'Saltea :count ocurrencias', - 'store_new_recurrence' => 'Almacenar transacción recurrente', + 'store_new_recurrence' => 'Crear transacción recurrente', 'stored_new_recurrence' => 'Transacción recurrente ":title" almacenada con éxito.', 'edit_recurrence' => 'Editar transacción recurrente ":title"', 'recurring_repeats_until' => 'Repetir hasta :date', diff --git a/resources/lang/es_ES/form.php b/resources/lang/es_ES/form.php index e4b8e3e370..c69e2a8589 100644 --- a/resources/lang/es_ES/form.php +++ b/resources/lang/es_ES/form.php @@ -30,31 +30,31 @@ return [ 'credit_card_limit' => 'Límite de la tarjeta de crédito', 'automatch' => 'Coinciden automáticamente', 'skip' => 'Saltar', - 'enabled' => 'Enabled', + 'enabled' => 'Habilitado', 'name' => 'Nombre', 'active' => 'Activo', 'amount_min' => 'Importe mínimo', 'amount_max' => 'Importe máximo', 'match' => 'Encuentros en', - 'strict' => 'Strict mode', + 'strict' => 'Modo estricto', 'repeat_freq' => 'Repetición', 'journal_currency_id' => 'Divisa', 'currency_id' => 'Divisa', - 'transaction_currency_id' => 'Currency', - 'external_ip' => 'Your server\'s external IP', + 'transaction_currency_id' => 'Moneda', + 'external_ip' => 'IP externa de su servidor', 'attachments' => 'Adjuntos', 'journal_amount' => 'Importe', - 'journal_source_name' => 'Revenue account (source)', - 'keep_bill_id' => 'Bill', - 'journal_source_id' => 'Asset account (source)', + 'journal_source_name' => 'Cuenta de ingresos (origen)', + 'keep_bill_id' => 'Factura', + 'journal_source_id' => 'Cuenta de activos (origen)', 'BIC' => 'BIC', 'verify_password' => 'Verificar la seguridad de contraseña', 'source_account' => 'Cuenta origen', 'destination_account' => 'Cuenta destino', - 'journal_destination_id' => 'Asset account (destination)', - 'asset_destination_account' => 'Destination account', - 'include_net_worth' => 'Include in net worth', - 'asset_source_account' => 'Source account', + 'journal_destination_id' => 'Cuenta de activos (destino)', + 'asset_destination_account' => 'Cuenta de destino', + 'include_net_worth' => 'Incluir en valor neto', + 'asset_source_account' => 'Cuenta de origen', 'journal_description' => 'Descripción', 'note' => 'Notas', 'split_journal' => 'Dividir esta transacción', @@ -87,9 +87,9 @@ return [ 'verification' => 'Verificación', 'api_key' => 'Clave de API', 'remember_me' => 'Recordarme', - 'liability_type_id' => 'Liability type', - 'interest' => 'Interest', - 'interest_period' => 'Interest period', + 'liability_type_id' => 'Tipo de pasivo', + 'interest' => 'Interés', + 'interest_period' => 'Período de interés', 'source_account_asset' => 'Cuenta de origen (cuenta de activos)', 'destination_account_expense' => 'Cuenta de destino (cuenta de gastos)', @@ -101,8 +101,8 @@ return [ 'convert_Transfer' => 'Convertir transferencia', 'amount' => 'Importe', - 'foreign_amount' => 'Foreign amount', - 'existing_attachments' => 'Existing attachments', + 'foreign_amount' => 'Cantidad extranjera', + 'existing_attachments' => 'Adjuntos existentes', 'date' => 'Fecha', 'interest_date' => 'Fecha de interés', 'book_date' => 'Fecha de registro', @@ -156,7 +156,7 @@ return [ 'delete_rule_group' => 'Eliminar grupo de reglas ":title"', 'delete_link_type' => 'Eliminar tipo de enlace ":name"', 'delete_user' => 'Eliminar usuario ":email"', - 'delete_recurring' => 'Delete recurring transaction ":title"', + 'delete_recurring' => 'Eliminar transacción recurrente ":title"', 'user_areYouSure' => 'Si elimina usuario ":email", todo desaparecerá. No hay deshacer, recuperar ni nada. Si te eliminas, perderás el acceso a esta instancia de Firefly III.', 'attachment_areYouSure' => '¿Seguro que quieres eliminar el archivo adjunto llamado "name"?', 'account_areYouSure' => '¿Seguro que quieres eliminar la cuenta llamada ":name"?', @@ -165,7 +165,7 @@ return [ 'ruleGroup_areYouSure' => '¿Seguro que quieres eliminar el grupo de reglas titulado ":title"?', 'budget_areYouSure' => '¿Seguro que quieres eliminar el presupuesto llamado ":name"?', 'category_areYouSure' => '¿Seguro que quieres eliminar la categoría llamada ":name"?', - 'recurring_areYouSure' => 'Are you sure you want to delete the recurring transaction titled ":title"?', + 'recurring_areYouSure' => '¿Está seguro de que desea eliminar la transacción recurrente ":title"?', 'currency_areYouSure' => '¿Está seguro que desea eliminar la moneda denominada ":name"?', 'piggyBank_areYouSure' => '¿Está seguro que desea eliminar la hucha llamada ":name"?', 'journal_areYouSure' => '¿Estás seguro de que deseas eliminar la transacción descrita ":description"?', @@ -173,19 +173,19 @@ return [ 'tag_areYouSure' => '¿Seguro que quieres eliminar la etiqueta ":tag"?', 'journal_link_areYouSure' => '¿Seguro que quieres eliminar el vínculo entre :source y :destination?', 'linkType_areYouSure' => '¿Estás seguro de que deseas eliminar el tipo de vínculo ":name" (":inward" / ":outward")?', - 'permDeleteWarning' => 'Deleting stuff from Firefly III is permanent and cannot be undone.', + 'permDeleteWarning' => 'Eliminar cosas de Firefly III es permanente y no se puede deshacer.', 'mass_make_selection' => 'Aún puede evitar que se eliminen elementos quitando la casilla de verificación.', 'delete_all_permanently' => 'Eliminar selección permanentemente', 'update_all_journals' => 'Actualiza estas transacciones', 'also_delete_transactions' => 'La única transacción conectada a esta cuenta también se eliminará. | Todas las :count transacciones conectadas a esta cuenta también se eliminarán.', 'also_delete_connections' => 'La única transacción vinculada con este tipo de enlace perderá esta conexión. | Todas las :count transacciones vinculadas con este tipo de enlace perderán su conexión.', 'also_delete_rules' => 'La única regla conectada a este grupo de reglas también se eliminará. | Todas las :count reglas conectadas a este grupo de reglas también se eliminarán.', - 'also_delete_piggyBanks' => 'La única alcancía conectada a esta cuenta también se eliminará. | Todas las :count alcancías conectadas a esta cuenta también se eliminará.', - 'bill_keep_transactions' => 'The only transaction connected to this bill will not be deleted.|All :count transactions connected to this bill will be spared deletion.', - 'budget_keep_transactions' => 'The only transaction connected to this budget will not be deleted.|All :count transactions connected to this budget will be spared deletion.', - 'category_keep_transactions' => 'The only transaction connected to this category will not be deleted.|All :count transactions connected to this category will be spared deletion.', - 'recurring_keep_transactions' => 'The only transaction created by this recurring transaction will not be deleted.|All :count transactions created by this recurring transaction will be spared deletion.', - 'tag_keep_transactions' => 'The only transaction connected to this tag will not be deleted.|All :count transactions connected to this tag will be spared deletion.', + 'also_delete_piggyBanks' => 'La hucha conectada a esta cuenta también se eliminará.|Las :count huchas conectadas a esta cuenta también se eliminarán.', + 'bill_keep_transactions' => 'La transacción conectada a esta factura no será eliminada.|Las :count transacciones conectadas a esta factura serán eliminadas.', + 'budget_keep_transactions' => 'La transacción conectada a este presupuesto no se eliminará.|Las :count transacciones conectadas a este presupuesto no serán eliminadas.', + 'category_keep_transactions' => 'La transacción conectada a esta categoría no se eliminará.|Las :count transacciones conectadas a esta categoría no serán eliminadas.', + 'recurring_keep_transactions' => 'La transacción conectada a esta transacción recurrente no se eliminará.|Las :count transacciones conectadas a esta transacción recurrente no serán eliminadas.', + 'tag_keep_transactions' => 'La transacción conectada a esta etiqueta no se eliminará.|Las :count transacciones conectadas a esta etiqueta no serán eliminadas.', 'check_for_updates' => 'Ver actualizaciones', 'email' => 'Correo electrónico', @@ -193,13 +193,13 @@ return [ 'password_confirmation' => 'Contraseña (otra vez)', 'blocked' => '¿Está bloqueado?', 'blocked_code' => 'Razón del bloqueo', - 'login_name' => 'Login', + 'login_name' => 'Iniciar sesión', // import - 'apply_rules' => 'Apply rules', - 'artist' => 'Artist', - 'album' => 'Album', - 'song' => 'Song', + 'apply_rules' => 'Aplicar reglas', + 'artist' => 'Artista', + 'album' => 'Álbum', + 'song' => 'Canción', // admin @@ -220,20 +220,20 @@ return [ 'client_id' => 'Identificación del cliente', 'service_secret' => 'Servicio secreto', 'app_secret' => 'Secreto de aplicación', - 'app_id' => 'App ID', - 'secret' => 'Secret', + 'app_id' => 'ID de la App', + 'secret' => 'Secreto', 'public_key' => 'Llave pública', 'country_code' => 'Código del país', 'provider_code' => 'Banco o proveedor de datos', - 'fints_url' => 'FinTS API URL', - 'fints_port' => 'Port', - 'fints_bank_code' => 'Bank code', - 'fints_username' => 'Username', - 'fints_password' => 'PIN / Password', - 'fints_account' => 'FinTS account', - 'local_account' => 'Firefly III account', - 'from_date' => 'Date from', - 'to_date' => 'Date to', + 'fints_url' => 'URL de la API de FinTS', + 'fints_port' => 'Puerto', + 'fints_bank_code' => 'Código bancario', + 'fints_username' => 'Usuario', + 'fints_password' => 'PIN / Contraseña', + 'fints_account' => 'Cuenta FinTS', + 'local_account' => 'Cuenta Firefly III', + 'from_date' => 'Fecha desde', + 'to_date' => 'Fecha hasta', 'due_date' => 'Fecha de vencimiento', @@ -243,17 +243,17 @@ return [ 'inward' => 'Descripción interna', 'outward' => 'Descripción externa', 'rule_group_id' => 'Grupo de reglas', - 'transaction_description' => 'Transaction description', - 'first_date' => 'First date', - 'transaction_type' => 'Transaction type', - 'repeat_until' => 'Repeat until', - 'recurring_description' => 'Recurring transaction description', - 'repetition_type' => 'Type of repetition', - 'foreign_currency_id' => 'Foreign currency', - 'repetition_end' => 'Repetition ends', - 'repetitions' => 'Repetitions', - 'calendar' => 'Calendar', - 'weekend' => 'Weekend', - 'client_secret' => 'Client secret', + 'transaction_description' => 'Descripción de la transacción', + 'first_date' => 'Primera fecha', + 'transaction_type' => 'Tipo de transacción', + 'repeat_until' => 'Repetir hasta', + 'recurring_description' => 'Descripción de transacción recurrente', + 'repetition_type' => 'Tipo de repetición', + 'foreign_currency_id' => 'Moneda extranjera', + 'repetition_end' => 'Termina la repetición', + 'repetitions' => 'Repeticiones', + 'calendar' => 'Calendario', + 'weekend' => 'Fin de semana', + 'client_secret' => 'Secreto del cliente', ]; diff --git a/resources/lang/es_ES/import.php b/resources/lang/es_ES/import.php index 3612b783cb..48911ac27d 100644 --- a/resources/lang/es_ES/import.php +++ b/resources/lang/es_ES/import.php @@ -25,9 +25,9 @@ declare(strict_types=1); return [ // ALL breadcrumbs and subtitles: 'index_breadcrumb' => 'Importar datos a Firefly III', - 'prerequisites_breadcrumb_fake' => 'Pre requisitos para el proveedor de importación falso', - 'prerequisites_breadcrumb_spectre' => 'Pre requisitos para Spectre', - 'prerequisites_breadcrumb_bunq' => 'Pre requisitos para bunq', + 'prerequisites_breadcrumb_fake' => 'Requisitos para el proveedor de importación falso', + 'prerequisites_breadcrumb_spectre' => 'Requisitos para bunq', + 'prerequisites_breadcrumb_bunq' => 'Requisitos para bunq', 'prerequisites_breadcrumb_ynab' => 'Pre requisitos para YNAB', 'job_configuration_breadcrumb' => 'Configuración para ":key"', 'job_status_breadcrumb' => 'Estado de importación de ":key"', @@ -91,7 +91,7 @@ return [ 'job_config_fake_album_title' => 'Introduzca el nombre del álbum', 'job_config_fake_album_text' => 'Algunas rutinas de importación requieren datos adicionales a medio camino a través de la importación. En el caso del proveedor de importación falso, debe responder algunas preguntas extrañas. Entra en "Estación a estación" para continuar.', // job configuration form the file provider - 'job_config_file_upload_title' => 'Importar configuración (1/4) - Subir archivo', + 'job_config_file_upload_title' => 'Configuración de importación (1/4) - Subir archivo', 'job_config_file_upload_text' => 'Esta rutina le ayudará a importar archivos de su banco en Firefly III. ', 'job_config_file_upload_help' => 'Seleccione su archivo. Por favor, asegúrese de que el archivo está codificado en UTF-8.', 'job_config_file_upload_config_help' => 'Si previamente ha importado datos en Firefly III, puede tener un archivo de configuración, el cual preestablecerá valores de configuración por usted. Para algunos bancos, otros usuarios han proporcionado amablemente sus archivo de configuración', @@ -100,7 +100,7 @@ return [ 'import_file_type_csv' => 'CSV (valores separados por comas)', 'import_file_type_ofx' => 'OFX', 'file_not_utf8' => 'El archivo que ha subido no es codificado como UTF-8 o ASCII. Firefly III no puede manejar este tipo de archivos. Utilice Notepad++ ó Sublime para convertir el archivo a UTF-8.', - 'job_config_uc_title' => 'Importación de configuración (2/4) - Archivo de configuración básica', + 'job_config_uc_title' => 'Configuración de importación (2/4) - Configuración básica de archivo', 'job_config_uc_text' => 'Para poder importar correctamente el archivo, por favor valide las opciones a continuación.', 'job_config_uc_header_help' => 'Marque esta casilla si la primera fila del archivo CSV son los títulos de columna.', 'job_config_uc_date_help' => 'Formato de fecha y hora en su archivo. Siga un formato como los que indica esta página. El valor por defecto interpretará fechas que se vean así: :dateExample.', @@ -131,14 +131,14 @@ return [ // job configuration for bunq: 'job_config_bunq_accounts_title' => 'cuentas de bunq', - 'job_config_bunq_accounts_text' => 'Estas son las cuentas asociadas a tu cuenta de bunq. Por favor, seleccione las cuentas desde las que desea importar, y en que cuenta deben importarse las transacciones.', + 'job_config_bunq_accounts_text' => 'Estas son las cuentas asociadas a tu cuenta de bunq. Por favor, seleccione las cuentas desde las que desea importar, y en qué cuenta deben importarse las transacciones.', 'bunq_no_mapping' => 'Parece que no ha seleccionado ninguna cuenta.', 'should_download_config' => 'Debería descargar el archivo de configuración para este trabajo. Esto hará las importaciones futuras de manera más fácil.', 'share_config_file' => 'Si ha importado los datos de un banco público, debe compartir su archivo de configuración para que sea fácil para otros usuarios importar sus propios datos. Compartiendo su archivo de configuración no expondrá sus datos financieros.', 'job_config_bunq_apply_rules' => 'Aplicar reglas', 'job_config_bunq_apply_rules_text' => 'De forma predeterminada, sus reglas se aplicarán a las transacciones creadas durante esta rutina de importación. Si no desea que esto suceda, desactive esta casilla de verificación.', - 'bunq_savings_goal' => 'Savings goal: :amount (:percentage%)', - 'bunq_account_status_CANCELLED' => 'Closed bunq account', + 'bunq_savings_goal' => 'Objetivo de ahorro: :amount (:percentage%)', + 'bunq_account_status_CANCELLED' => 'Cuenta de bunq cerrada', 'ynab_account_closed' => '¡La cuenta ha sido cerrada!', 'ynab_account_deleted' => '¡La cuenta ha sido borrada!', @@ -175,8 +175,8 @@ return [ 'spectre_extra_key_account_name' => 'Nombre de la cuenta', 'spectre_extra_key_client_name' => 'Nombre del cliente', 'spectre_extra_key_account_number' => 'Número de cuenta', - 'spectre_extra_key_blocked_amount' => 'Monto bloqueado', - 'spectre_extra_key_available_amount' => 'Monto disponible', + 'spectre_extra_key_blocked_amount' => 'Cantidad bloqueada', + 'spectre_extra_key_available_amount' => 'Cantidad disponible', 'spectre_extra_key_credit_limit' => 'Limite de crédito', 'spectre_extra_key_interest_rate' => 'Tasa de interés', 'spectre_extra_key_expiry_date' => 'Fecha de vencimiento', @@ -186,7 +186,7 @@ return [ 'spectre_extra_key_cards' => 'Tarjetas', 'spectre_extra_key_units' => 'Unidades', 'spectre_extra_key_unit_price' => 'Precio unitario', - 'spectre_extra_key_transactions_count' => 'Nro. de transacciones', + 'spectre_extra_key_transactions_count' => 'Nº de transacciones', //job configuration for finTS 'fints_connection_failed' => 'Se ha producido un error al intentar conectar a su banco. Por favor, asegúrese de que todos los datos que escribió son correctos. Mensaje de error original: :originalError', @@ -208,7 +208,7 @@ return [ 'specific_pres_name' => 'President\'s Choice Financial CA', 'specific_pres_descr' => 'Soluciona problemas potenciales con archivos de PC', // job configuration for file provider (stage: roles) - 'job_config_roles_title' => 'Importar configuración (3/4) - definir el papel de cada columna', + 'job_config_roles_title' => 'Configuración de importación (3/4) - Definir el rol de cada columna', 'job_config_roles_text' => 'Cada columna en su archivo CSV contiene ciertos datos. Indique qué tipo de datos debe esperar el importador. La opción de "mapear" datos significa que enlazará cada entrada encontrada en la columna con un valor en su base de datos. Una columna a menudo mapeada es la columna que contiene el IBAN de la cuenta de contrapartida. Eso puede enlazarse fácilmente con cuentas IBAN ya presentes en su base de datos.', 'job_config_roles_submit' => 'Continuar', 'job_config_roles_column_name' => 'Nombre de la columna', @@ -220,7 +220,7 @@ return [ 'job_config_roles_rwarning' => 'Por lo menos, marque una columna como la columna de importe. También es aconsejable seleccionar una columna para la descripción. la fecha y la cuenta contraria.', 'job_config_roles_colum_count' => 'Columna', // job config for the file provider (stage: mapping): - 'job_config_map_title' => 'Importar configuración (4/4) - Conecta datos de importación a los datos de Firefly III', + 'job_config_map_title' => 'Configuración de importación (4/4) - Conectar datos importados a datos de Firefly III', 'job_config_map_text' => 'En las siguientes tablas, el valor de la izquierda muestra información encontrada en el archivo cargado. Es su tarea mapear este valor, si es posible, a un valor ya presente en su base de datos. Firefly Iii respetará este mapeo. Si no hay un valor hacia el cual mapear o no se desea mapear un valor especifico, no seleccione ninguno.', 'job_config_map_nothing' => 'No hay datos presentes en su archivo que pueda asignar a los valores existentes. Por favor presione "comenzar la importación" para continuar.', 'job_config_field_value' => 'Valor del campo', @@ -259,10 +259,10 @@ return [ 'column_account-name' => 'Caja de ahorros (nombre)', 'column_account-bic' => 'Caja de ahorro (BIC)', 'column_amount' => 'Cantidad', - 'column_amount_foreign' => 'Monto ( en moneda extranjera)', + 'column_amount_foreign' => 'Cantidad (en moneda extranjera)', 'column_amount_debit' => 'Cantidad (columna de débito)', 'column_amount_credit' => 'Cantidad (columna de crédito)', - 'column_amount_negated' => 'Amount (negated column)', + 'column_amount_negated' => 'Cantidad (columna negada)', 'column_amount-comma-separated' => 'Cantidad (coma como decimal separador)', 'column_bill-id' => 'ID factura (coincide FF3)', 'column_bill-name' => 'Nombre de la factura', @@ -279,8 +279,8 @@ return [ 'column_date-book' => 'Fecha de registro de la transacción', 'column_date-process' => 'Fecha del proceso de transacción', 'column_date-transaction' => 'Fecha', - 'column_date-due' => 'Transaction due date', - 'column_date-payment' => 'Transaction payment date', + 'column_date-due' => 'Fecha de vencimiento de la transacción', + 'column_date-payment' => 'Fecha de pago de transacción', 'column_date-invoice' => 'Fecha de la factura de la transacción', 'column_description' => 'Descripción', 'column_opposing-iban' => 'Cuenta opuesta (IBAN)', @@ -290,7 +290,7 @@ return [ 'column_opposing-name' => 'Cuenta opuesta (nombre)', 'column_rabo-debit-credit' => 'Indicador especifico débito/crédito de Rabobank', 'column_ing-debit-credit' => 'Indicador especifico débito/crédito de ING', - 'column_generic-debit-credit' => 'Generic bank debit/credit indicator', + 'column_generic-debit-credit' => 'Indicador de débito/crédito de bancos genéricos', 'column_sepa-ct-id' => 'Identificador de end-to-end SEPA', 'column_sepa-ct-op' => 'Identificador de cuenta opuesta SEPA', 'column_sepa-db' => 'Identificador de mandato SEPA', @@ -298,7 +298,7 @@ return [ 'column_sepa-ci' => 'Identificador de acreedor SEPA', 'column_sepa-ep' => 'Propósito externo SEPA', 'column_sepa-country' => 'Código del país SEPA', - 'column_sepa-batch-id' => 'SEPA Batch ID', + 'column_sepa-batch-id' => 'ID de lote SEPA', 'column_tags-comma' => 'Etiquetas ( separadas por comas)', 'column_tags-space' => 'Etiquetas ( separadas por espacio)', 'column_account-number' => 'Cuenta de archivos ( numero de cuenta)', diff --git a/resources/lang/es_ES/intro.php b/resources/lang/es_ES/intro.php index db9bcaf350..fafde8a9f4 100644 --- a/resources/lang/es_ES/intro.php +++ b/resources/lang/es_ES/intro.php @@ -43,7 +43,7 @@ return [ 'budgets_index_see_expenses_bar' => 'Gastar dinero irá llenando poco a poco esta barra.', 'budgets_index_navigate_periods' => 'Navega a través de períodos para configurar fácilmente presupuestos con anticipación.', 'budgets_index_new_budget' => 'Crea nuevos presupuestos como mejor te parezca.', - 'budgets_index_list_of_budgets' => 'Use esta tabla para establecer el monto de cada presupuesto y ver como lo viene administrando.', + 'budgets_index_list_of_budgets' => 'Use esta tabla para establecer las cantidades para cada presupuesto y ver cómo está haciendo.', 'budgets_index_outro' => 'Para aprender mas acerca de los presupuestos, revise el icono de ayuda en el tope de la esquina derecha.', // reports (index) @@ -79,9 +79,9 @@ return [ 'transactions_create_transfer_ffInput_piggy_bank_id' => 'Seleccione una alcancía y vincule esta transferencia con sus ahorros.', // piggy banks index: - 'piggy-banks_index_saved' => 'Este campo le muestra cuanto ha ahorrado usted en cada alcancía.', - 'piggy-banks_index_button' => 'Junto con esta barra de progreso hay dos botones (+ y -) para añadir o eliminar dinero de cada alcancía.', - 'piggy-banks_index_accountStatus' => 'Para cada cuenta de activos con al menos una alcancía, el estado esta listado en esta tabla.', + 'piggy-banks_index_saved' => 'Este campo le muestra cuánto ha ahorrado usted en cada hucha.', + 'piggy-banks_index_button' => 'Junto con esta barra de progreso hay dos botones (+ y -) para añadir o quitar dinero de cada hucha.', + 'piggy-banks_index_accountStatus' => 'Para cada cuenta de activos con al menos una hucha, el estado está listado en esta tabla.', // create piggy 'piggy-banks_create_name' => '¿Cuál es tu meta? ¿Un nuevo sofá, una cámara, dinero para emergencias?', @@ -89,7 +89,7 @@ return [ // show piggy 'piggy-banks_show_piggyChart' => 'Este informe le mostrara la historia de esta alcancía.', - 'piggy-banks_show_piggyDetails' => 'Algunos detalles sobre tu alcancía', + 'piggy-banks_show_piggyDetails' => 'Algunos detalles sobre tu hucha', 'piggy-banks_show_piggyEvents' => 'Cualquier adición o eliminación también se listan aquí.', // bill index @@ -130,8 +130,8 @@ return [ // currencies 'currencies_index_intro' => 'Firefly III da soporte a múltiples monedas, que usted puede cambiar en esta página.', - 'currencies_index_default' => 'Firefly III has one default currency.', - 'currencies_index_buttons' => 'Use these buttons to change the default currency or enable other currencies.', + 'currencies_index_default' => 'Firefly III tiene una moneda por defecto.', + 'currencies_index_buttons' => 'Utilice estos botones para cambiar la moneda por defecto o habilitar otras monedas.', // create currency 'currencies_create_code' => 'Este código debe ser compatible con ISO (Googlee para su nueva moneda).', diff --git a/resources/lang/es_ES/list.php b/resources/lang/es_ES/list.php index 006804ac01..f1b4d471a5 100644 --- a/resources/lang/es_ES/list.php +++ b/resources/lang/es_ES/list.php @@ -34,15 +34,15 @@ return [ 'name' => 'Nombre', 'role' => 'Rol', 'currentBalance' => 'Balance actual', - 'linked_to_rules' => 'Relevant rules', + 'linked_to_rules' => 'Reglas asociadas', 'active' => '¿Está Activo?', 'lastActivity' => 'Actividad más reciente', - 'balanceDiff' => 'Diferencia de equilibrio', + 'balanceDiff' => 'Diferencia de saldo', 'matchesOn' => 'Encontrado en', 'account_type' => 'Tipo de cuenta', 'created_at' => 'Fecha de creación', 'account' => 'Cuenta', - 'matchingAmount' => 'Monto', + 'matchingAmount' => 'Cantidad', 'split_number' => 'División #', 'destination' => 'Destino', 'source' => 'Origen', @@ -104,18 +104,18 @@ return [ 'sum_transfers' => 'Suma de transferencias', 'reconcile' => 'Reconciliar', 'account_on_spectre' => 'Cuenta (espectro)', - 'account_on_ynab' => 'Account (YNAB)', + 'account_on_ynab' => 'Cuenta (YNAB)', 'do_import' => 'Importar desde esta cuenta', - 'sepa-ct-id' => 'SEPA End to End Identifier', - 'sepa-ct-op' => 'SEPA Opposing Account Identifier', - 'sepa-db' => 'SEPA Mandate Identifier', - 'sepa-country' => 'SEPA Country', - 'sepa-cc' => 'SEPA Clearing Code', - 'sepa-ep' => 'SEPA External Purpose', - 'sepa-ci' => 'SEPA Creditor Identifier', - 'sepa-batch-id' => 'SEPA Batch ID', + 'sepa-ct-id' => 'Identificador de extremo a extremo SEPA', + 'sepa-ct-op' => 'Identificador de cuenta opuesta SEPA', + 'sepa-db' => 'Identificador de mandato SEPA', + 'sepa-country' => 'País SEPA', + 'sepa-cc' => 'Código de limpieza SEPA', + 'sepa-ep' => 'Propósito externo SEPA', + 'sepa-ci' => 'Identificador de acreedor SEPA', + 'sepa-batch-id' => 'ID de lote SEPA', 'external_id' => 'ID Externo', - 'account_at_bunq' => 'Account with bunq', + 'account_at_bunq' => 'Cuenta con bunq', 'file_name' => 'Nombre de fichero', 'file_size' => 'Tamaño de fichero', 'file_type' => 'Tipo de fichero', @@ -124,13 +124,13 @@ return [ 'spectre_bank' => 'Banco', 'spectre_last_use' => 'Ultimó acceso', 'spectre_status' => 'Estado', - 'bunq_payment_id' => 'bunq payment ID', + 'bunq_payment_id' => 'ID de pago bunq', 'repetitions' => 'Repeticiones', 'title' => 'Título', - 'transaction_s' => 'Transaction(s)', + 'transaction_s' => 'Transacción(es)', 'field' => 'Campo', 'value' => 'Valor', 'interest' => 'Interés', - 'interest_period' => 'interest period', - 'liability_type' => 'Type of liability', + 'interest_period' => 'período de interés', + 'liability_type' => 'Tipo de pasivo', ]; diff --git a/resources/lang/es_ES/validation.php b/resources/lang/es_ES/validation.php index 86f7e75f21..8845556901 100644 --- a/resources/lang/es_ES/validation.php +++ b/resources/lang/es_ES/validation.php @@ -24,8 +24,8 @@ declare(strict_types=1); return [ 'iban' => 'Este no es un IBAN válido.', - 'zero_or_more' => 'The value cannot be negative.', - 'date_or_time' => 'The value must be a valid date or time value (ISO 8601).', + 'zero_or_more' => 'El valor no puede ser negativo.', + 'date_or_time' => 'El valor debe ser una fecha u hora válido (ISO 8601).', 'source_equals_destination' => 'La cuenta origen es igual que la cuenta destino.', 'unique_account_number_for_user' => 'Parece que este número de cuenta ya está en uso.', 'unique_iban_for_user' => 'Parece que este IBAN ya está en uso.', @@ -89,7 +89,7 @@ return [ 'max.array' => 'El campo :attribute debe contener al menos :max elementos.', 'mimes' => 'El campo :attribute debe ser un archivo de tipo :values.', 'min.numeric' => 'El campo :attribute debe ser al menos :min.', - 'lte.numeric' => 'The :attribute must be less than or equal :value.', + 'lte.numeric' => 'El :attribute debe ser menor o igual :value.', 'min.file' => 'El campo :attribute debe ser al menos :min kilobytes.', 'min.string' => 'El campo :attribute debe contener al menos :min caracteres.', 'min.array' => 'El campo :attribute debe tener al menos :min elementos.', @@ -124,22 +124,22 @@ return [ 'present' => 'El campo :attribute debe estar presente.', 'amount_zero' => 'La cantidad total no puede ser cero.', 'unique_piggy_bank_for_user' => 'En nombre de la hucha debe ser único.', - 'secure_password' => 'This is not a secure password. Please try again. For more information, visit https://bit.ly/FF3-password-security', + 'secure_password' => 'Esta contraseña no es segura. Por favor inténtalo de nuevo. Para más información, visita https://bit.ly/FF3-password-security', 'valid_recurrence_rep_type' => 'Tipo de repetición no válido para transacciones recurrentes.', 'valid_recurrence_rep_moment' => 'Momento de repetición no válido para este tipo de repetición.', 'invalid_account_info' => 'Información de cuenta no válida.', 'attributes' => [ 'email' => 'dirección de correo electrónico', 'description' => 'descripcion', - 'amount' => 'monto', + 'amount' => 'cantidad', 'name' => 'nombre', 'piggy_bank_id' => 'ID de hucha', - 'targetamount' => 'monto objetivo', + 'targetamount' => 'cantidad objetivo', 'openingBalanceDate' => 'fecha de balance de apertura', 'openingBalance' => 'balance de apertura', 'match' => 'emparejar', - 'amount_min' => 'monto minimo', - 'amount_max' => 'monto maximo', + 'amount_min' => 'cantidad mínima', + 'amount_max' => 'cantidad máxima', 'title' => 'título', 'tag' => 'etiqueta', 'transaction_description' => 'Descripción de la transacción', diff --git a/resources/lang/fr_FR/firefly.php b/resources/lang/fr_FR/firefly.php index 759a414a7d..641dd0b7ba 100644 --- a/resources/lang/fr_FR/firefly.php +++ b/resources/lang/fr_FR/firefly.php @@ -217,7 +217,27 @@ return [ // search 'search' => 'Rechercher', 'search_query' => 'Requête', - 'search_found_transactions' => 'Nombre de transactions trouvées :', + 'search_found_transactions' => 'Firefly III found :count transaction(s) in :time seconds.', + 'search_for_query' => 'Firefly III is searching for transactions with all of these words in them: :query', + 'search_modifier_amount_is' => 'Amount is exactly :value', + 'search_modifier_amount' => 'Amount is exactly :value', + 'search_modifier_amount_max' => 'Amount is at most :value', + 'search_modifier_amount_min' => 'Amount is at least :value', + 'search_modifier_amount_less' => 'Amount is less than :value', + 'search_modifier_amount_more' => 'Amount is more than :value', + 'search_modifier_source' => 'Source account is :value', + 'search_modifier_destination' => 'Destination account is :value', + 'search_modifier_category' => 'Category is :value', + 'search_modifier_budget' => 'Budget is :value', + 'search_modifier_bill' => 'Bill is :value', + 'search_modifier_type' => 'Transaction type is :value', + 'search_modifier_date' => 'Transaction date is :value', + 'search_modifier_date_before' => 'Transaction date is before :value', + 'search_modifier_date_after' => 'Transaction date is after :value', + 'search_modifier_on' => 'Transaction date is :value', + 'search_modifier_before' => 'Transaction date is before :value', + 'search_modifier_after' => 'Transaction date is after :value', + 'modifiers_applies_are' => 'The following modifiers are applied to the search as well:', 'general_search_error' => 'Une erreur s’est produite lors de la recherche. S’il vous plaît vérifiez les fichiers de log pour plus d’informations.', 'search_box' => 'Rechercher', 'search_box_intro' => 'Bienvenue à la fonction de recherche de Firefly III. Entrez votre requête de recherche dans la zone. Assurez-vous de consulter le fichier d’aide parce que la recherche est assez avancée.', diff --git a/resources/lang/id_ID/firefly.php b/resources/lang/id_ID/firefly.php index be83f21da4..ab5ee4aad4 100644 --- a/resources/lang/id_ID/firefly.php +++ b/resources/lang/id_ID/firefly.php @@ -217,7 +217,27 @@ return [ // search 'search' => 'Pencarian', 'search_query' => 'Pertanyaan', - 'search_found_transactions' => 'Jumlah transaksi yang ditemukan:', + 'search_found_transactions' => 'Firefly III found :count transaction(s) in :time seconds.', + 'search_for_query' => 'Firefly III is searching for transactions with all of these words in them: :query', + 'search_modifier_amount_is' => 'Amount is exactly :value', + 'search_modifier_amount' => 'Amount is exactly :value', + 'search_modifier_amount_max' => 'Amount is at most :value', + 'search_modifier_amount_min' => 'Amount is at least :value', + 'search_modifier_amount_less' => 'Amount is less than :value', + 'search_modifier_amount_more' => 'Amount is more than :value', + 'search_modifier_source' => 'Source account is :value', + 'search_modifier_destination' => 'Destination account is :value', + 'search_modifier_category' => 'Category is :value', + 'search_modifier_budget' => 'Budget is :value', + 'search_modifier_bill' => 'Bill is :value', + 'search_modifier_type' => 'Transaction type is :value', + 'search_modifier_date' => 'Transaction date is :value', + 'search_modifier_date_before' => 'Transaction date is before :value', + 'search_modifier_date_after' => 'Transaction date is after :value', + 'search_modifier_on' => 'Transaction date is :value', + 'search_modifier_before' => 'Transaction date is before :value', + 'search_modifier_after' => 'Transaction date is after :value', + 'modifiers_applies_are' => 'The following modifiers are applied to the search as well:', 'general_search_error' => 'Terjadi kesalahan saat mencari. Silakan periksa file log untuk informasi lebih lanjut.', 'search_box' => 'Pencarian', 'search_box_intro' => 'Selamat datang di fungsi pencarian Firefly III. Masukkan kueri penelusuran Anda di dalam kotak. Pastikan Anda memeriksa file bantuan karena pencariannya cukup canggih.', diff --git a/resources/lang/it_IT/firefly.php b/resources/lang/it_IT/firefly.php index 7896bf8701..17c52fca9e 100644 --- a/resources/lang/it_IT/firefly.php +++ b/resources/lang/it_IT/firefly.php @@ -217,7 +217,27 @@ return [ // search 'search' => 'Cerca', 'search_query' => 'Domanda', - 'search_found_transactions' => 'Numero di transizioni trovate:', + 'search_found_transactions' => 'Firefly III found :count transaction(s) in :time seconds.', + 'search_for_query' => 'Firefly III is searching for transactions with all of these words in them: :query', + 'search_modifier_amount_is' => 'Amount is exactly :value', + 'search_modifier_amount' => 'Amount is exactly :value', + 'search_modifier_amount_max' => 'Amount is at most :value', + 'search_modifier_amount_min' => 'Amount is at least :value', + 'search_modifier_amount_less' => 'Amount is less than :value', + 'search_modifier_amount_more' => 'Amount is more than :value', + 'search_modifier_source' => 'Source account is :value', + 'search_modifier_destination' => 'Destination account is :value', + 'search_modifier_category' => 'Category is :value', + 'search_modifier_budget' => 'Budget is :value', + 'search_modifier_bill' => 'Bill is :value', + 'search_modifier_type' => 'Transaction type is :value', + 'search_modifier_date' => 'Transaction date is :value', + 'search_modifier_date_before' => 'Transaction date is before :value', + 'search_modifier_date_after' => 'Transaction date is after :value', + 'search_modifier_on' => 'Transaction date is :value', + 'search_modifier_before' => 'Transaction date is before :value', + 'search_modifier_after' => 'Transaction date is after :value', + 'modifiers_applies_are' => 'The following modifiers are applied to the search as well:', 'general_search_error' => 'Si è verificato un errore durante la ricerca. Si prega di controllare i file di registro per ulteriori informazioni.', 'search_box' => 'Ricerca', 'search_box_intro' => 'Benvenuto nella funzione di ricerca di Firefly III. Inserisci la query di ricerca nella casella. Assicurati di controllare il file della guida perché la ricerca è abbastanza avanzata.', diff --git a/resources/lang/nl_NL/firefly.php b/resources/lang/nl_NL/firefly.php index 3894775e99..4d72450a31 100644 --- a/resources/lang/nl_NL/firefly.php +++ b/resources/lang/nl_NL/firefly.php @@ -217,7 +217,27 @@ return [ // search 'search' => 'Zoeken', 'search_query' => 'Zoekopdracht', - 'search_found_transactions' => 'Aantal gevonden transacties:', + 'search_found_transactions' => 'Firefly III vond :count transactie(s) in :time seconden.', + 'search_for_query' => 'Firefly III zoekt transacties met al deze woorden: :query', + 'search_modifier_amount_is' => 'Bedrag is precies :value', + 'search_modifier_amount' => 'Bedrag is precies :value', + 'search_modifier_amount_max' => 'Bedrag is hoogstens :value', + 'search_modifier_amount_min' => 'Bedrag is minstens :value', + 'search_modifier_amount_less' => 'Bedrag is minder dan :value', + 'search_modifier_amount_more' => 'Bedrag is meer dan :value', + 'search_modifier_source' => 'Bronrekening is :value', + 'search_modifier_destination' => 'Doelrekening is :value', + 'search_modifier_category' => 'Categorie is :value', + 'search_modifier_budget' => 'Budget is :value', + 'search_modifier_bill' => 'Contract is :value', + 'search_modifier_type' => 'Transactietype is :value', + 'search_modifier_date' => 'Transactiedatum is :value', + 'search_modifier_date_before' => 'Transactiedatum is vóór :value', + 'search_modifier_date_after' => 'Transactiedatum is na :value', + 'search_modifier_on' => 'Transactiedatum is :value', + 'search_modifier_before' => 'Transactiedatum is vóór :value', + 'search_modifier_after' => 'Transactiedatum is na :value', + 'modifiers_applies_are' => 'De volgende wijzigingen worden ook toegepast op de zoekopdracht:', 'general_search_error' => 'Er is een fout opgetreden tijdens het zoeken. Controleer de log-bestanden voor meer informatie.', 'search_box' => 'Zoeken', 'search_box_intro' => 'Welkom bij de zoekfunctie van Firefly III. Voer je zoekopdracht in het vak. Bekijk zeker de help-pagina, want de zoekfunctie is behoorlijk geadvanceerd.', diff --git a/resources/lang/pl_PL/firefly.php b/resources/lang/pl_PL/firefly.php index 72e929c0b0..3b246b1881 100644 --- a/resources/lang/pl_PL/firefly.php +++ b/resources/lang/pl_PL/firefly.php @@ -217,7 +217,27 @@ return [ // search 'search' => 'Szukaj', 'search_query' => 'Zapytanie', - 'search_found_transactions' => 'Liczba znalezionych transakcji:', + 'search_found_transactions' => 'Firefly III found :count transaction(s) in :time seconds.', + 'search_for_query' => 'Firefly III is searching for transactions with all of these words in them: :query', + 'search_modifier_amount_is' => 'Amount is exactly :value', + 'search_modifier_amount' => 'Amount is exactly :value', + 'search_modifier_amount_max' => 'Amount is at most :value', + 'search_modifier_amount_min' => 'Amount is at least :value', + 'search_modifier_amount_less' => 'Amount is less than :value', + 'search_modifier_amount_more' => 'Amount is more than :value', + 'search_modifier_source' => 'Source account is :value', + 'search_modifier_destination' => 'Destination account is :value', + 'search_modifier_category' => 'Category is :value', + 'search_modifier_budget' => 'Budget is :value', + 'search_modifier_bill' => 'Bill is :value', + 'search_modifier_type' => 'Transaction type is :value', + 'search_modifier_date' => 'Transaction date is :value', + 'search_modifier_date_before' => 'Transaction date is before :value', + 'search_modifier_date_after' => 'Transaction date is after :value', + 'search_modifier_on' => 'Transaction date is :value', + 'search_modifier_before' => 'Transaction date is before :value', + 'search_modifier_after' => 'Transaction date is after :value', + 'modifiers_applies_are' => 'The following modifiers are applied to the search as well:', 'general_search_error' => 'Wystąpił błąd podczas wyszukiwania. Aby uzyskać więcej informacji proszę sprawdzić logi aplikacji.', 'search_box' => 'Szukaj', 'search_box_intro' => 'Witamy w funkcji wyszukiwania Firefly III. Wpisz zapytanie w polu. Upewnij się, że sprawdziłeś plik pomocy, ponieważ wyszukiwanie jest dość zaawansowane.', diff --git a/resources/lang/pt_BR/firefly.php b/resources/lang/pt_BR/firefly.php index 89a117d456..437795541b 100644 --- a/resources/lang/pt_BR/firefly.php +++ b/resources/lang/pt_BR/firefly.php @@ -217,7 +217,27 @@ return [ // search 'search' => 'Pesquisa', 'search_query' => 'Pedido', - 'search_found_transactions' => 'Número de transações encontradas:', + 'search_found_transactions' => 'Firefly III found :count transaction(s) in :time seconds.', + 'search_for_query' => 'Firefly III is searching for transactions with all of these words in them: :query', + 'search_modifier_amount_is' => 'Amount is exactly :value', + 'search_modifier_amount' => 'Amount is exactly :value', + 'search_modifier_amount_max' => 'Amount is at most :value', + 'search_modifier_amount_min' => 'Amount is at least :value', + 'search_modifier_amount_less' => 'Amount is less than :value', + 'search_modifier_amount_more' => 'Amount is more than :value', + 'search_modifier_source' => 'Source account is :value', + 'search_modifier_destination' => 'Destination account is :value', + 'search_modifier_category' => 'Category is :value', + 'search_modifier_budget' => 'Budget is :value', + 'search_modifier_bill' => 'Bill is :value', + 'search_modifier_type' => 'Transaction type is :value', + 'search_modifier_date' => 'Transaction date is :value', + 'search_modifier_date_before' => 'Transaction date is before :value', + 'search_modifier_date_after' => 'Transaction date is after :value', + 'search_modifier_on' => 'Transaction date is :value', + 'search_modifier_before' => 'Transaction date is before :value', + 'search_modifier_after' => 'Transaction date is after :value', + 'modifiers_applies_are' => 'The following modifiers are applied to the search as well:', 'general_search_error' => 'Ocorreu um erro durante a pesquisa. Verifique os arquivos de log para obter mais informações.', 'search_box' => 'Pesquisar', 'search_box_intro' => 'Bem-vindo à função de pesquisa do Firefly III. Digite sua consulta de pesquisa na caixa. Certifique-se de verificar o arquivo de ajuda porque a pesquisa é bastante avançada.', diff --git a/resources/lang/ru_RU/firefly.php b/resources/lang/ru_RU/firefly.php index f0a73b4b04..42bdea9b16 100644 --- a/resources/lang/ru_RU/firefly.php +++ b/resources/lang/ru_RU/firefly.php @@ -217,7 +217,27 @@ return [ // search 'search' => 'Поиск', 'search_query' => 'Запрос', - 'search_found_transactions' => 'Количество транзакций найдено:', + 'search_found_transactions' => 'Firefly III found :count transaction(s) in :time seconds.', + 'search_for_query' => 'Firefly III is searching for transactions with all of these words in them: :query', + 'search_modifier_amount_is' => 'Amount is exactly :value', + 'search_modifier_amount' => 'Amount is exactly :value', + 'search_modifier_amount_max' => 'Amount is at most :value', + 'search_modifier_amount_min' => 'Amount is at least :value', + 'search_modifier_amount_less' => 'Amount is less than :value', + 'search_modifier_amount_more' => 'Amount is more than :value', + 'search_modifier_source' => 'Source account is :value', + 'search_modifier_destination' => 'Destination account is :value', + 'search_modifier_category' => 'Category is :value', + 'search_modifier_budget' => 'Budget is :value', + 'search_modifier_bill' => 'Bill is :value', + 'search_modifier_type' => 'Transaction type is :value', + 'search_modifier_date' => 'Transaction date is :value', + 'search_modifier_date_before' => 'Transaction date is before :value', + 'search_modifier_date_after' => 'Transaction date is after :value', + 'search_modifier_on' => 'Transaction date is :value', + 'search_modifier_before' => 'Transaction date is before :value', + 'search_modifier_after' => 'Transaction date is after :value', + 'modifiers_applies_are' => 'The following modifiers are applied to the search as well:', 'general_search_error' => 'Произошла ошибка при поиске. Пожалуйста, проверьте файлы журнала для получения дополнительной информации.', 'search_box' => 'Поиск', 'search_box_intro' => 'Добро пожаловать в функцию поиска Firefly III. Введите поисковый запрос в поле. Убедитесь, что вы ознакомились с инструкцией, потому что поиск достаточно продвинутый.', diff --git a/resources/lang/tr_TR/firefly.php b/resources/lang/tr_TR/firefly.php index 3f5fdc875c..3fc11bee3a 100644 --- a/resources/lang/tr_TR/firefly.php +++ b/resources/lang/tr_TR/firefly.php @@ -219,7 +219,27 @@ return [ // search 'search' => 'Ara', 'search_query' => 'Sorgu', - 'search_found_transactions' => 'Bulunan işlem sayısı:', + 'search_found_transactions' => 'Firefly III found :count transaction(s) in :time seconds.', + 'search_for_query' => 'Firefly III is searching for transactions with all of these words in them: :query', + 'search_modifier_amount_is' => 'Amount is exactly :value', + 'search_modifier_amount' => 'Amount is exactly :value', + 'search_modifier_amount_max' => 'Amount is at most :value', + 'search_modifier_amount_min' => 'Amount is at least :value', + 'search_modifier_amount_less' => 'Amount is less than :value', + 'search_modifier_amount_more' => 'Amount is more than :value', + 'search_modifier_source' => 'Source account is :value', + 'search_modifier_destination' => 'Destination account is :value', + 'search_modifier_category' => 'Category is :value', + 'search_modifier_budget' => 'Budget is :value', + 'search_modifier_bill' => 'Bill is :value', + 'search_modifier_type' => 'Transaction type is :value', + 'search_modifier_date' => 'Transaction date is :value', + 'search_modifier_date_before' => 'Transaction date is before :value', + 'search_modifier_date_after' => 'Transaction date is after :value', + 'search_modifier_on' => 'Transaction date is :value', + 'search_modifier_before' => 'Transaction date is before :value', + 'search_modifier_after' => 'Transaction date is after :value', + 'modifiers_applies_are' => 'The following modifiers are applied to the search as well:', 'general_search_error' => 'Arama yapılırken bir hata oluştu. Daha fazla bilgi için günlük dosyalarına bakın.', 'search_box' => 'Ara', 'search_box_intro' => 'Firefly III\'ün arama fonksiyonuna hoş geldiniz. Kutuya arama sorgunuzu giriniz. Arama oldukça gelişmiş olduğundan yardım dosyasını kontrol ettiğinizden emin olun.', diff --git a/resources/lang/zh_CN/firefly.php b/resources/lang/zh_CN/firefly.php index 81b0da1185..1eb56a32d3 100644 --- a/resources/lang/zh_CN/firefly.php +++ b/resources/lang/zh_CN/firefly.php @@ -217,7 +217,27 @@ return [ // search 'search' => '搜寻', 'search_query' => '查询', - 'search_found_transactions' => '已找到交易数量:', + 'search_found_transactions' => 'Firefly III found :count transaction(s) in :time seconds.', + 'search_for_query' => 'Firefly III is searching for transactions with all of these words in them: :query', + 'search_modifier_amount_is' => 'Amount is exactly :value', + 'search_modifier_amount' => 'Amount is exactly :value', + 'search_modifier_amount_max' => 'Amount is at most :value', + 'search_modifier_amount_min' => 'Amount is at least :value', + 'search_modifier_amount_less' => 'Amount is less than :value', + 'search_modifier_amount_more' => 'Amount is more than :value', + 'search_modifier_source' => 'Source account is :value', + 'search_modifier_destination' => 'Destination account is :value', + 'search_modifier_category' => 'Category is :value', + 'search_modifier_budget' => 'Budget is :value', + 'search_modifier_bill' => 'Bill is :value', + 'search_modifier_type' => 'Transaction type is :value', + 'search_modifier_date' => 'Transaction date is :value', + 'search_modifier_date_before' => 'Transaction date is before :value', + 'search_modifier_date_after' => 'Transaction date is after :value', + 'search_modifier_on' => 'Transaction date is :value', + 'search_modifier_before' => 'Transaction date is before :value', + 'search_modifier_after' => 'Transaction date is after :value', + 'modifiers_applies_are' => 'The following modifiers are applied to the search as well:', 'general_search_error' => '在搜索时发生错误,请前往log files查看更错信息。', 'search_box' => '搜寻', 'search_box_intro' => '欢迎使用 Firefly III 的搜寻功能,请于方框内键入搜寻条件。请确保您以阅读过协助档案,因为此搜寻功能非常先进。', diff --git a/resources/lang/zh_TW/firefly.php b/resources/lang/zh_TW/firefly.php index 70471ab0f5..2d0b55e08a 100644 --- a/resources/lang/zh_TW/firefly.php +++ b/resources/lang/zh_TW/firefly.php @@ -42,13 +42,13 @@ return [ 'from' => '自', 'to' => '至', 'structure' => '結構', - 'help_translating' => '本說明文本於您的語言尚不可用,願意協助嗎?', + 'help_translating' => '本處說明的中文版欠奉,要協助翻譯嗎?', 'showEverything' => '全部顯示', 'never' => '未有資料', 'no_results_for_empty_search' => '您的搜尋為空,找不到任何東西。', 'removed_amount' => '已移除 :amount', 'added_amount' => '已新增 :amount', - 'asset_account_role_help' => '基於您的選擇而產生的額外選項,均可於事後調整。', + 'asset_account_role_help' => '選擇後如有額外選項,可稍後設定。', 'Opening balance' => '初始餘額', 'create_new_stuff' => '建立新內容', 'new_withdrawal' => '新提款', @@ -77,7 +77,7 @@ return [ 'flash_info_multiple' => '有1個訊息|有 :count 個訊息', 'flash_error_multiple' => '有1個錯誤|有 :count 個錯誤', 'net_worth' => '淨值', - 'route_has_no_help' => '此路徑目前還沒有說明。', + 'route_has_no_help' => '此處尚未提供說明。', 'help_for_this_page' => '本頁說明', 'no_help_could_be_found' => '找不到說明文本。', 'no_help_title' => '不好意思,發生一個錯誤。', @@ -111,7 +111,7 @@ return [ 'income_by_category' => '按分類的收入', 'expenses_by_asset_account' => '按資產帳戶的支出', 'expenses_by_expense_account' => '按支出帳戶的支出', - 'cannot_redirect_to_account' => 'Firefly III 無法重新指向您至正確頁面,抱歉。', + 'cannot_redirect_to_account' => 'Firefly III 無法重新導向正確頁面,抱歉。', 'sum_of_expenses' => '支出總和', 'sum_of_income' => '收入總和', 'liabilities' => '債務', @@ -217,7 +217,27 @@ return [ // search 'search' => '搜尋', 'search_query' => '查询', - 'search_found_transactions' => '已找到交易數量:', + 'search_found_transactions' => 'Firefly III found :count transaction(s) in :time seconds.', + 'search_for_query' => 'Firefly III is searching for transactions with all of these words in them: :query', + 'search_modifier_amount_is' => 'Amount is exactly :value', + 'search_modifier_amount' => 'Amount is exactly :value', + 'search_modifier_amount_max' => 'Amount is at most :value', + 'search_modifier_amount_min' => 'Amount is at least :value', + 'search_modifier_amount_less' => 'Amount is less than :value', + 'search_modifier_amount_more' => 'Amount is more than :value', + 'search_modifier_source' => 'Source account is :value', + 'search_modifier_destination' => 'Destination account is :value', + 'search_modifier_category' => 'Category is :value', + 'search_modifier_budget' => 'Budget is :value', + 'search_modifier_bill' => 'Bill is :value', + 'search_modifier_type' => 'Transaction type is :value', + 'search_modifier_date' => 'Transaction date is :value', + 'search_modifier_date_before' => 'Transaction date is before :value', + 'search_modifier_date_after' => 'Transaction date is after :value', + 'search_modifier_on' => 'Transaction date is :value', + 'search_modifier_before' => 'Transaction date is before :value', + 'search_modifier_after' => 'Transaction date is after :value', + 'modifiers_applies_are' => 'The following modifiers are applied to the search as well:', 'general_search_error' => '在搜索时发生错误,请前往log files查看更错信息。', 'search_box' => '搜尋', 'search_box_intro' => '歡迎使用 Firefly III 的搜尋功能,請於方框內鍵入搜尋條件。請確保您以閱讀過協助檔案,因為此搜尋功能非常先進。', diff --git a/resources/views/v1/bills/show.twig b/resources/views/v1/bills/show.twig index 26afa17311..4665d9c7fd 100644 --- a/resources/views/v1/bills/show.twig +++ b/resources/views/v1/bills/show.twig @@ -129,9 +129,9 @@ {% endif %} ({{ att.size|filesize }}) - {% if att.description %} + {% if att.notes.first %}
- {{ att.description }} + {{ att.notes.first.text|markdown }} {% endif %} diff --git a/resources/views/v1/layout/default.twig b/resources/views/v1/layout/default.twig index 4c7a08f7ab..0658a1fd7f 100644 --- a/resources/views/v1/layout/default.twig +++ b/resources/views/v1/layout/default.twig @@ -6,6 +6,8 @@ + + {% if subTitle %} {{ subTitle }} » diff --git a/resources/views/v1/layout/empty.twig b/resources/views/v1/layout/empty.twig index d45d1236bb..a7b8a3343e 100644 --- a/resources/views/v1/layout/empty.twig +++ b/resources/views/v1/layout/empty.twig @@ -8,6 +8,7 @@ <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="csrf-token" content="{{ csrf_token() }}"> <meta content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no' name='viewport'> + <meta name="apple-mobile-web-app-capable" content="yes"> {# CSS things #} diff --git a/resources/views/v1/layout/guest.twig b/resources/views/v1/layout/guest.twig index cd5f2eb525..2224271f13 100644 --- a/resources/views/v1/layout/guest.twig +++ b/resources/views/v1/layout/guest.twig @@ -4,6 +4,8 @@ <base href="{{ route('index') }}/"> <meta charset="UTF-8"> <meta name="robots" content="noindex, nofollow, noarchive, noodp, NoImageIndex, noydir"> + <meta name="apple-mobile-web-app-capable" content="yes"> + <title>Firefly III {% if title != "Firefly" and title != "" %} diff --git a/resources/views/v1/layout/install.twig b/resources/views/v1/layout/install.twig index d8dff67371..7374e94621 100644 --- a/resources/views/v1/layout/install.twig +++ b/resources/views/v1/layout/install.twig @@ -8,6 +8,7 @@ <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="csrf-token" content="{{ csrf_token() }}"> <meta content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no' name='viewport'> + <meta name="apple-mobile-web-app-capable" content="yes"> <link href="v1/css/app.css?v={{ FF_VERSION }}" rel="stylesheet" type="text/css"/> <link href="v1/lib/adminlte/css/AdminLTE.min.css?v={{ FF_VERSION }}" rel="stylesheet" type="text/css"/> <link href="v1/css/firefly.css?v={{ FF_VERSION }}" rel="stylesheet" type="text/css"/> diff --git a/resources/views/v1/search/index.twig b/resources/views/v1/search/index.twig index b9f5fe9ebd..90b174b21e 100644 --- a/resources/views/v1/search/index.twig +++ b/resources/views/v1/search/index.twig @@ -20,7 +20,8 @@ <div class="form-group"> <label for="query" class="col-sm-1 control-label">{{ 'search_query'|_ }}</label> <div class="col-sm-10"> - <input autocomplete="off" type="text" name="q" id="query" value="{{ fullQuery }}" class="form-control" placeholder="{{ fullQuery }}"> + <input autocomplete="off" type="text" name="q" id="query" value="{{ fullQuery }}" class="form-control" + placeholder="{{ fullQuery }}"> </div> </div> <div class="form-group"> @@ -29,6 +30,17 @@ </div> </div> </form> + <p> + {{ trans('firefly.search_for_query', {query: query})|raw}} + </p> + {% if modifiers|length > 0 %} + <p>{{ trans('firefly.modifiers_applies_are') }}</p> + <ul> + {% for modifier in modifiers %} + <li>{{ trans('firefly.search_modifier_'~modifier.type, {value: modifier.value}) }}</li> + {% endfor %} + </ul> + {% endif %} </div> </div> </div> @@ -44,11 +56,7 @@ <p class="search_ongoing text-center" style="margin-top:70px;"> {{ 'search_searching'|_ }} </p> - <p class="search_count" style="display: none;"> - {{ 'search_found_transactions'|_ }} <span class="search_count"></span> - </p> - <div class="search_results" style="display: none;"> - </div> + <div class="search_results" style="display: none;"></div> {# loading indicator #} <div class="overlay"> <i class="fa fa-refresh fa-spin"></i> diff --git a/resources/views/v1/search/search.twig b/resources/views/v1/search/search.twig index f325bb9666..756d24578d 100644 --- a/resources/views/v1/search/search.twig +++ b/resources/views/v1/search/search.twig @@ -1,3 +1,8 @@ +<p> +<p class="search_count"> + {{ trans('firefly.search_found_transactions', {count: transactions.count, time: searchTime}) }} +</p> + <table class="table table-hover table-condensed"> <thead> <tr class="ignore"> diff --git a/tests/Feature/Controllers/SearchControllerTest.php b/tests/Feature/Controllers/SearchControllerTest.php index a8444f388b..b14b148ebb 100644 --- a/tests/Feature/Controllers/SearchControllerTest.php +++ b/tests/Feature/Controllers/SearchControllerTest.php @@ -24,6 +24,7 @@ namespace Tests\Feature\Controllers; use FireflyIII\Repositories\User\UserRepositoryInterface; use FireflyIII\Support\Search\SearchInterface; +use Illuminate\Pagination\LengthAwarePaginator; use Illuminate\Support\Collection; use Log; use Mockery; @@ -61,6 +62,7 @@ class SearchControllerTest extends TestCase $search->shouldReceive('parseQuery')->once(); $search->shouldReceive('getWordsAsString')->once()->andReturn('test'); + $search->shouldReceive('getModifiers')->once()->andReturn(new Collection); $this->be($this->user()); $response = $this->get(route('search.index') . '?q=test'); $response->assertStatus(200); @@ -78,7 +80,8 @@ class SearchControllerTest extends TestCase $search->shouldReceive('parseQuery')->once(); $search->shouldReceive('setLimit')->withArgs([50])->once(); - $search->shouldReceive('searchTransactions')->once()->andReturn(new Collection); + $search->shouldReceive('searchTransactions')->once()->andReturn(new LengthAwarePaginator([],0,10)); + $search->shouldReceive('searchTime')->once()->andReturn(0.2); $this->be($this->user()); diff --git a/tests/Unit/Support/NavigationTest.php b/tests/Unit/Support/NavigationTest.php new file mode 100644 index 0000000000..80d1458305 --- /dev/null +++ b/tests/Unit/Support/NavigationTest.php @@ -0,0 +1,344 @@ +<?php +/** + * NavigationTest.php + * Copyright (c) 2019 thegrumpydictator@gmail.com + * + * This file is part of Firefly III. + * + * Firefly III is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Firefly III 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. + */ + +declare(strict_types=1); + +namespace Tests\Unit\Support; + + +use Carbon\Carbon; +use FireflyIII\Exceptions\FireflyException; +use FireflyIII\Support\Navigation; +use Log; +use Tests\TestCase; + +/** + * + * Class NavigationTest + */ +class NavigationTest extends TestCase +{ + + /** + * + */ + public function setUp(): void + { + parent::setUp(); + Log::info(sprintf('Now in %s.', \get_class($this))); + } + + /** + * @covers \FireflyIII\Support\Navigation + */ + public function testAddPeriod(): void + { + $tests = [ + // period, skip, start, expected end + ['1D', 0, '2018-01-01', '2018-01-02'], + ['1D', 1, '2018-01-01', '2018-01-03'], + ['1D', 1, '2018-02-28', '2018-03-02'], + ['1W', 0, '2015-02-28', '2015-03-07'], + ['1W', 0, '2016-02-28', '2016-03-06'], // leap year + ['1W', 1, '2015-02-28', '2015-03-14'], + ['1W', 1, '2016-02-28', '2016-03-13'], // leap year + ['1W', 0, '2018-01-01', '2018-01-08'], + + ['1M', 0, '2018-01-01', '2018-02-01'], + ['1M', 0, '2018-02-01', '2018-03-01'], + ['1M', 0, '2018-01-28', '2018-02-28'], + ['1M', 0, '2016-01-29', '2016-02-29'], // leap year makes it work + ['1M', 0, '2019-01-29', '2019-02-28'], // jump to end of next month. + ['1M', 0, '2019-01-30', '2019-02-28'], // jump to end of next month. + ['1M', 0, '2019-01-31', '2019-02-28'], // jump to end of next month. + ['1M', 0, '2019-02-01', '2019-03-01'], + ['1M', 1, '2019-02-01', '2019-03-31'], // weird but OK. + ['1M', 2, '2019-01-01', '2019-04-01'], + + ['quarter', 0, '2019-01-01', '2019-04-01'], + ['quarter', 1, '2019-01-01', '2019-07-01'], + + ['6M', 0, '2019-01-01', '2019-07-01'], + ['6M', 1, '2019-01-01', '2020-01-01'], + ['6M', 0, '2019-08-01', '2020-02-01'], + + ['year', 0, '2019-01-01', '2020-01-01'], + ['year', 1, '2019-01-01', '2021-01-01'], + ['custom', 1, '2019-01-01', '2019-03-01'], + + ]; + + /** @var array $test */ + foreach ($tests as $test) { + + $freq = $test[0]; + /** @noinspection MultiAssignmentUsageInspection */ + $skip = $test[1]; + $start = new Carbon($test[2]); + $expected = new Carbon($test[3]); + $nav = new Navigation; + try { + $result = $nav->addPeriod($start, $freq, $skip); + } catch (FireflyException $e) { + $this->assertFalse(true, $e->getMessage()); + } + + $this->assertEquals($expected->format('Y-m-d'), $result->format('Y-m-d')); + } + } + + /** + * @covers \FireflyIII\Support\Navigation + */ + public function testAddPeriodError(): void + { + $tests = [ + // period, skip, start, expected end + ['bla', 0, '2018-01-01', '2018-01-02'], + ]; + + /** @var array $test */ + foreach ($tests as $test) { + + $freq = $test[0]; + /** @noinspection MultiAssignmentUsageInspection */ + $skip = $test[1]; + $start = new Carbon($test[2]); + $nav = new Navigation; + try { + $nav->addPeriod($start, $freq, $skip); + } catch (FireflyException $e) { + $this->assertEquals('Cannot do addPeriod for $repeat_freq "bla"', $e->getMessage()); + } + } + } + + /** + * @covers \FireflyIII\Support\Navigation + */ + public function testBlockPeriods(): void + { + $tests = [ + [ + 'start' => '2014-01-01', + 'end' => '2018-12-31', + 'range' => '1M', + 'expected' => + [ + [ + 'start' => '2018-12-01', + 'end' => '2018-12-31', + 'period' => '1M', + ], + [ + 'start' => '2018-11-01', + 'end' => '2018-11-30', + 'period' => '1M', + ], + [ + 'start' => '2018-10-01', + 'end' => '2018-10-31', + 'period' => '1M', + ], + [ + 'start' => '2018-09-01', + 'end' => '2018-09-30', + 'period' => '1M', + ], + [ + 'start' => '2018-08-01', + 'end' => '2018-08-31', + 'period' => '1M', + ], + [ + 'start' => '2018-07-01', + 'end' => '2018-07-31', + 'period' => '1M', + ], + [ + 'start' => '2018-06-01', + 'end' => '2018-06-30', + 'period' => '1M', + ], + [ + 'start' => '2018-05-01', + 'end' => '2018-05-31', + 'period' => '1M', + ], + [ + 'start' => '2018-04-01', + 'end' => '2018-04-30', + 'period' => '1M', + ], + [ + 'start' => '2018-03-01', + 'end' => '2018-03-31', + 'period' => '1M', + ], + [ + 'start' => '2018-02-01', + 'end' => '2018-02-28', + 'period' => '1M', + ], + [ + 'start' => '2018-01-01', + 'end' => '2018-01-31', + 'period' => '1M', + ], + [ + 'start' => '2017-12-01', + 'end' => '2017-12-31', + 'period' => '1M', + ], + [ + 'start' => '2017-11-01', + 'end' => '2017-11-30', + 'period' => '1M', + ], + [ + 'start' => '2017-10-01', + 'end' => '2017-10-31', + 'period' => '1M', + ], + [ + 'start' => '2017-09-01', + 'end' => '2017-09-30', + 'period' => '1M', + ], + [ + 'start' => '2017-08-01', + 'end' => '2017-08-31', + 'period' => '1M', + ], + [ + 'start' => '2017-07-01', + 'end' => '2017-07-31', + 'period' => '1M', + ], + [ + 'start' => '2017-06-01', + 'end' => '2017-06-30', + 'period' => '1M', + ], + [ + 'start' => '2017-05-01', + 'end' => '2017-05-31', + 'period' => '1M', + ], + [ + 'start' => '2017-04-01', + 'end' => '2017-04-30', + 'period' => '1M', + ], + [ + 'start' => '2017-03-01', + 'end' => '2017-03-31', + 'period' => '1M', + ], + [ + 'start' => '2017-02-01', + 'end' => '2017-02-28', + 'period' => '1M', + ], + [ + 'start' => '2017-01-01', + 'end' => '2017-01-31', + 'period' => '1M', + ], + [ + 'start' => '2016-01-01', + 'end' => '2016-12-31', + 'period' => '1Y', + ], + [ + 'start' => '2015-01-01', + 'end' => '2015-12-31', + 'period' => '1Y', + ], + [ + 'start' => '2014-01-01', + 'end' => '2014-12-31', + 'period' => '1Y', + ], + ] + + , + ], + ]; + + /** @var array $test */ + foreach ($tests as $test) { + + $start = new Carbon($test['start']); + $end = new Carbon($test['end']); + $range = $test['range']; + $nav = new Navigation; + try { + $result = $nav->blockPeriods($start, $end, $range); + } catch (FireflyException $e) { + $this->assertFalse(true, $e->getMessage()); + } + $parsedResult = []; + foreach ($result as $entry) { + $parsedResult[] = [ + 'start' => $entry['start']->format('Y-m-d'), + 'end' => $entry['end']->format('Y-m-d'), + 'period' => $entry['period'], + ]; + } + $this->assertEquals($test['expected'], $parsedResult); + + } + } + + /** + * @covers \FireflyIII\Support\Navigation + */ + public function testEndOfPeriod(): void + { + + $tests = [ + ['1D', '2018-01-01 00:00:00', '2018-01-01 23:59:59'], + ['1W', '2018-01-01 00:00:00', '2018-01-07 23:59:59'], + ['1M', '2018-01-01 00:00:00', '2018-01-31 23:59:59'], + ['3M', '2018-01-01 00:00:00', '2018-03-31 23:59:59'], + ['6M', '2018-01-01 00:00:00', '2018-06-30 23:59:59'], + ['1Y', '2018-01-01 00:00:00', '2018-12-31 23:59:59'], + ]; + + /** @var array $test */ + foreach ($tests as $test) { + + $freq = $test[0]; + /** @noinspection MultiAssignmentUsageInspection */ + $start = new Carbon($test[1]); + $expected = new Carbon($test[2]); + $nav = new Navigation; + try { + $result = $nav->endOfPeriod($start, $freq); + } catch (FireflyException $e) { + $this->assertFalse(true, $e->getMessage()); + } + + $this->assertEquals($expected->format('Y-m-d H:i:s'), $result->format('Y-m-d H:i:s')); + } + } +} \ No newline at end of file