diff --git a/.env.docker b/.env.docker
index 28b1973148..20f4436f77 100644
--- a/.env.docker
+++ b/.env.docker
@@ -95,4 +95,5 @@ DEMO_PASSWORD=
IS_DOCKER=true
IS_SANDSTORM=false
IS_HEROKU=false
+BUNQ_USE_SANDBOX=false
TZ=${TZ}
diff --git a/.env.example b/.env.example
index 2f2f38771a..e45753a2ca 100644
--- a/.env.example
+++ b/.env.example
@@ -98,4 +98,5 @@ DEMO_USERNAME=
DEMO_PASSWORD=
IS_DOCKER=false
IS_SANDSTORM=false
+BUNQ_USE_SANDBOX=false
IS_HEROKU=false
diff --git a/.env.heroku b/.env.heroku
index e25675664d..91e273659a 100644
--- a/.env.heroku
+++ b/.env.heroku
@@ -98,4 +98,5 @@ DEMO_USERNAME=
DEMO_PASSWORD=
IS_DOCKER=false
IS_SANDSTORM=false
+BUNQ_USE_SANDBOX=false
IS_HEROKU=true
diff --git a/.env.sandstorm b/.env.sandstorm
index 8aa9358af8..c72676704c 100755
--- a/.env.sandstorm
+++ b/.env.sandstorm
@@ -98,4 +98,5 @@ DEMO_USERNAME=
DEMO_PASSWORD=
IS_DOCKER=false
IS_SANDSTORM=true
+BUNQ_USE_SANDBOX=false
IS_HEROKU=false
diff --git a/.env.testing b/.env.testing
index 04b6a2b328..943ab13502 100644
--- a/.env.testing
+++ b/.env.testing
@@ -94,4 +94,5 @@ DEMO_USERNAME=
DEMO_PASSWORD=
IS_DOCKER=false
IS_SANDSTORM=false
+BUNQ_USE_SANDBOX=true
IS_HEROKU=false
diff --git a/.github/ISSUE_TEMPLATE/Bug_report.md b/.github/ISSUE_TEMPLATE/Bug_report.md
new file mode 100644
index 0000000000..1312de943a
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/Bug_report.md
@@ -0,0 +1,22 @@
+---
+name: Bug report
+about: Create a report to help Firefly III improve
+
+---
+
+**Bug description**
+I am running Firefly III version x.x.x
+
+(please give a clear and concise description of what the bug is)
+
+**Steps to reproduce**
+What do you need to do to trigger this bug?
+
+**Extra info**
+Please add extra info here, such as OS, browser, and the output from the `/debug`-page of your Firefly III installation (click the version at the bottom).
+
+**Bonus points**
+Earn bonus points by:
+
+- Post a stacktrace from your log files
+- Add a screenshot
\ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE/Custom.md b/.github/ISSUE_TEMPLATE/Custom.md
new file mode 100644
index 0000000000..f943c935cb
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/Custom.md
@@ -0,0 +1,25 @@
+---
+name: I have a question or a problem
+about: Ask away
+
+---
+
+I am running Firefly III version x.x.x
+
+**Description of my issue:**
+
+
+**Steps to reproduce**
+
+(please include if this problem also exists on the demo site: https://demo.firefly-iii.org/ )
+
+**Extra info**
+
+Please add extra info here, such as OS, browser, and the output from the `/debug`-page of your Firefly III installation (click the version at the bottom).
+
+**Bonus points**
+Earn bonus points by:
+
+- Post a stacktrace from your log files
+- Add a screenshot
+- Post nginx or Apache configuration
\ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE/Feature_request.md b/.github/ISSUE_TEMPLATE/Feature_request.md
new file mode 100644
index 0000000000..7dfae270ae
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/Feature_request.md
@@ -0,0 +1,20 @@
+---
+name: Feature request
+about: Suggest an idea or feature for Firefly III
+
+---
+
+**Description**
+Please describe your feature request:
+
+- I would like Firefly III to do X.
+- What if you would add Y?
+
+**Solution**
+Describe what your feature would add to Firefly III.
+
+**What are alternatives?**
+Please describe what alternatives currently exist.
+
+**Additional context**
+Add any other context or screenshots about the feature request here.
\ No newline at end of file
diff --git a/.github/issue_template.md b/.github/issue_template.md
deleted file mode 100644
index d1640a0f27..0000000000
--- a/.github/issue_template.md
+++ /dev/null
@@ -1,11 +0,0 @@
-I am running Firefly III version x.x.x
-
-#### Description of my issue:
-
-#### Steps to reproduce
-
-(please include if this problem also exists on the demo site)
-
-#### Other important details (log files, system info):
-
-Please click the version number in the right corner of any Firefly III page to get debug information.
\ No newline at end of file
diff --git a/.sandstorm/changelog.md b/.sandstorm/changelog.md
index 9f8550f563..c46086da90 100644
--- a/.sandstorm/changelog.md
+++ b/.sandstorm/changelog.md
@@ -1,7 +1,31 @@
+# 4.7.4
+- [Issue 1409](https://github.com/firefly-iii/firefly-iii/issues/1409), add Indian Rupee and explain that users can do this themselves [issue 1413](https://github.com/firefly-iii/firefly-iii/issues/1413)
+- [Issue 1445](https://github.com/firefly-iii/firefly-iii/issues/1445), upgrade Curl in Docker image.
+- [Issue 1386](https://github.com/firefly-iii/firefly-iii/issues/1386), quick links to often used pages.
+- [Issue 1405](https://github.com/firefly-iii/firefly-iii/issues/1405), show proposed amount to piggy banks.
+- [Issue 1416](https://github.com/firefly-iii/firefly-iii/issues/1416), ability to delete lost attachments.
+- A completely rewritten import routine that can handle bunq (thanks everybody for testing!), CSV files and Spectre. Please make sure you read about this at http://bit.ly/FF3-new-import
+- [Issue 1392](https://github.com/firefly-iii/firefly-iii/issues/1392), explicitly mention rules are inactive (when they are).
+- [Issue 1406](https://github.com/firefly-iii/firefly-iii/issues/1406), bill conversion to rules will be smarter about the rules they create.
+- [Issue 1369](https://github.com/firefly-iii/firefly-iii/issues/1369), you can now properly order piggy banks again.
+- [Issue 1389](https://github.com/firefly-iii/firefly-iii/issues/1389), null-pointer in the import routine.
+- [Issue 1400](https://github.com/firefly-iii/firefly-iii/issues/1400), missing translation.
+- [Issue 1403](https://github.com/firefly-iii/firefly-iii/issues/1403), bill would always be marked as inactive in edit screen.
+- [Issue 1418](https://github.com/firefly-iii/firefly-iii/issues/1418), missing note text on bill page.
+- Export routine would break when encountering un-decryptable files.
+- [Issue 1425](https://github.com/firefly-iii/firefly-iii/issues/1425), empty fields when edit multiple transactions at once.
+- [Issue 1449](https://github.com/firefly-iii/firefly-iii/issues/1449), bad calculations in "budget left to spend" view.
+- [Issue 1451](https://github.com/firefly-iii/firefly-iii/issues/1451), same but in another view.
+- [Issue 1453](https://github.com/firefly-iii/firefly-iii/issues/1453), same as [issue 1403](https://github.com/firefly-iii/firefly-iii/issues/1403).
+- [Issue 1455](https://github.com/firefly-iii/firefly-iii/issues/1455), could add income to a budget.
+- [Issue 1442](https://github.com/firefly-iii/firefly-iii/issues/1442), issues with editing a split deposit.
+- [Issue 1452](https://github.com/firefly-iii/firefly-iii/issues/1452), date range problems with tags.
+- [Issue 1458](https://github.com/firefly-iii/firefly-iii/issues/1458), same for transactions.
+- [Issue 1415](https://github.com/firefly-iii/firefly-iii/issues/1415), will email you when OAuth2 keys are generated.
+
# 4.7.3.2
- Forgot to increase the version number :(.
-
# 4.7.3.1
- Fixed a critical bug where the rules-engine would fire inadvertently.
diff --git a/.sandstorm/sandstorm-pkgdef.capnp b/.sandstorm/sandstorm-pkgdef.capnp
index 239821c66b..6f5c532bd3 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 = 12,
- appMarketingVersion = (defaultText = "4.7.3.2"),
+ appVersion = 13,
+ appMarketingVersion = (defaultText = "4.7.4"),
actions = [
# Define your "new document" handlers here.
diff --git a/Dockerfile b/Dockerfile
index 05884d9350..e9619b7ee4 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -3,6 +3,8 @@ FROM php:7.1-apache
# set working dir
ENV FIREFLY_PATH /var/www/firefly-iii
+ENV CURL_VERSION 7.60.0
+ENV OPENSSL_VERSION 1.1.1-pre6
WORKDIR $FIREFLY_PATH
ADD . $FIREFLY_PATH
@@ -11,7 +13,8 @@ RUN apt-get update -y && \
apt-get install -y --no-install-recommends libcurl4-openssl-dev \
zlib1g-dev \
libjpeg62-turbo-dev \
- libpng12-dev \
+ wget \
+ libpng-dev \
libicu-dev \
libedit-dev \
libtidy-dev \
@@ -24,6 +27,26 @@ RUN apt-get update -y && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
+# Setup the Composer installer
+RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
+
+# Install latest curl
+RUN cd /tmp && \
+ wget https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz && \
+ tar -xvf openssl-${OPENSSL_VERSION}.tar.gz && \
+ cd openssl-${OPENSSL_VERSION} && \
+ ./config && \
+ make && \
+ make install
+
+RUN cd /tmp && \
+ wget https://curl.haxx.se/download/curl-${CURL_VERSION}.tar.gz && \
+ tar -xvf curl-${CURL_VERSION}.tar.gz && \
+ cd curl-${CURL_VERSION} && \
+ ./configure --with-ssl && \
+ make && \
+ make install
+
# Install PHP exentions.
RUN docker-php-ext-install -j$(nproc) curl gd intl json readline tidy zip bcmath xml mbstring pdo_sqlite pdo_mysql bz2 pdo_pgsql
@@ -42,9 +65,6 @@ RUN a2enmod ssl
# Create volumes for several directories:
VOLUME $FIREFLY_PATH/storage/export $FIREFLY_PATH/storage/upload
-# Setup the Composer installer
-RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
-
# Enable default site (Firefly III)
COPY ./.deploy/docker/apache-firefly.conf /etc/apache2/sites-available/000-default.conf
@@ -58,4 +78,5 @@ RUN composer install --prefer-dist --no-dev --no-scripts --no-suggest
EXPOSE 80
# Run entrypoint thing
-ENTRYPOINT [".deploy/docker/entrypoint.sh"]
\ No newline at end of file
+ENTRYPOINT [".deploy/docker/entrypoint.sh"]
+
diff --git a/app/Api/V1/Controllers/AboutController.php b/app/Api/V1/Controllers/AboutController.php
index e7fcc291c3..77e63b7c64 100644
--- a/app/Api/V1/Controllers/AboutController.php
+++ b/app/Api/V1/Controllers/AboutController.php
@@ -1,5 +1,5 @@
.
*/
+declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers;
diff --git a/app/Api/V1/Controllers/AccountController.php b/app/Api/V1/Controllers/AccountController.php
index cff7969f6f..2f951fed3b 100644
--- a/app/Api/V1/Controllers/AccountController.php
+++ b/app/Api/V1/Controllers/AccountController.php
@@ -1,5 +1,5 @@
.
*/
+declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers;
diff --git a/app/Api/V1/Controllers/BillController.php b/app/Api/V1/Controllers/BillController.php
index bbf38c444d..420b01dc16 100644
--- a/app/Api/V1/Controllers/BillController.php
+++ b/app/Api/V1/Controllers/BillController.php
@@ -1,5 +1,5 @@
.
*/
+declare(strict_types=1);
+
namespace FireflyIII\Api\V1\Controllers;
use FireflyIII\Api\V1\Requests\BillRequest;
diff --git a/app/Api/V1/Controllers/Controller.php b/app/Api/V1/Controllers/Controller.php
index ba49f812aa..a212ad3029 100644
--- a/app/Api/V1/Controllers/Controller.php
+++ b/app/Api/V1/Controllers/Controller.php
@@ -1,5 +1,5 @@
.
*/
+declare(strict_types=1);
+
namespace FireflyIII\Api\V1\Controllers;
use Carbon\Carbon;
diff --git a/app/Api/V1/Controllers/TransactionController.php b/app/Api/V1/Controllers/TransactionController.php
index 99ea62de2a..f0dbc2b246 100644
--- a/app/Api/V1/Controllers/TransactionController.php
+++ b/app/Api/V1/Controllers/TransactionController.php
@@ -1,5 +1,5 @@
.
*/
+declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers;
diff --git a/app/Api/V1/Controllers/UserController.php b/app/Api/V1/Controllers/UserController.php
index 1cf1bece04..f2759f9e71 100644
--- a/app/Api/V1/Controllers/UserController.php
+++ b/app/Api/V1/Controllers/UserController.php
@@ -1,5 +1,5 @@
.
*/
+declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers;
diff --git a/app/Api/V1/Requests/AccountRequest.php b/app/Api/V1/Requests/AccountRequest.php
index 44977d41e2..5a287b85ed 100644
--- a/app/Api/V1/Requests/AccountRequest.php
+++ b/app/Api/V1/Requests/AccountRequest.php
@@ -1,5 +1,5 @@
.
*/
+declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests;
diff --git a/app/Api/V1/Requests/BillRequest.php b/app/Api/V1/Requests/BillRequest.php
index f2e13aaf9f..9f68a656cd 100644
--- a/app/Api/V1/Requests/BillRequest.php
+++ b/app/Api/V1/Requests/BillRequest.php
@@ -1,5 +1,5 @@
.
*/
+declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests;
diff --git a/app/Api/V1/Requests/CurrencyRequest.php b/app/Api/V1/Requests/CurrencyRequest.php
index 72666a3a77..8e2edfeda9 100644
--- a/app/Api/V1/Requests/CurrencyRequest.php
+++ b/app/Api/V1/Requests/CurrencyRequest.php
@@ -80,4 +80,4 @@ class CurrencyRequest extends Request
return $rules;
}
-}
\ No newline at end of file
+}
diff --git a/app/Api/V1/Requests/Request.php b/app/Api/V1/Requests/Request.php
index 509c092956..e2016dba34 100644
--- a/app/Api/V1/Requests/Request.php
+++ b/app/Api/V1/Requests/Request.php
@@ -1,5 +1,5 @@
.
*/
+declare(strict_types=1);
+
namespace FireflyIII\Api\V1\Requests;
use FireflyIII\Http\Requests\Request as FireflyIIIRequest;
diff --git a/app/Api/V1/Requests/TransactionRequest.php b/app/Api/V1/Requests/TransactionRequest.php
index 2b7ce5c0f9..ab03ec561a 100644
--- a/app/Api/V1/Requests/TransactionRequest.php
+++ b/app/Api/V1/Requests/TransactionRequest.php
@@ -1,5 +1,5 @@
.
*/
+declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests;
diff --git a/app/Api/V1/Requests/UserRequest.php b/app/Api/V1/Requests/UserRequest.php
index 2a1d76fe86..ba9bf54904 100644
--- a/app/Api/V1/Requests/UserRequest.php
+++ b/app/Api/V1/Requests/UserRequest.php
@@ -1,5 +1,5 @@
.
*/
+declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests;
diff --git a/app/Console/Commands/CreateExport.php b/app/Console/Commands/CreateExport.php
index 658dce8505..336c5718ff 100644
--- a/app/Console/Commands/CreateExport.php
+++ b/app/Console/Commands/CreateExport.php
@@ -1,8 +1,8 @@
.
*/
+declare(strict_types=1);
+
namespace FireflyIII\Console\Commands;
use Carbon\Carbon;
diff --git a/app/Console/Commands/CreateImport.php b/app/Console/Commands/CreateImport.php
index 209ed068cf..8c23105c0a 100644
--- a/app/Console/Commands/CreateImport.php
+++ b/app/Console/Commands/CreateImport.php
@@ -1,8 +1,8 @@
.
*/
+declare(strict_types=1);
+
namespace FireflyIII\Console\Commands;
+use Exception;
use FireflyIII\Exceptions\FireflyException;
+use FireflyIII\Import\Prerequisites\PrerequisitesInterface;
use FireflyIII\Import\Routine\RoutineInterface;
+use FireflyIII\Import\Storage\ImportArrayStorage;
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
use FireflyIII\Repositories\User\UserRepositoryInterface;
-use FireflyIII\Services\Internal\File\EncryptService;
use Illuminate\Console\Command;
-use Illuminate\Support\MessageBag;
use Log;
use Preferences;
@@ -52,18 +55,17 @@ class CreateImport extends Command
*/
protected $signature
= 'firefly:create-import
- {file : The file to import.}
- {configuration : The configuration file to use for the import.}
+ {file? : The file to import.}
+ {configuration? : The configuration file to use for the import.}
{--type=csv : The file type of the import.}
- {--user= : The user ID that the import should import for.}
+ {--provider=file : The file type of the import.}
+ {--user=1 : The user ID that the import should import for.}
{--token= : The user\'s access token.}
{--start : Starts the job immediately.}';
/**
* Run the command.
*
- * @noinspection MultipleReturnStatementsInspection
- *
* @throws FireflyException
*/
public function handle(): int
@@ -74,77 +76,155 @@ class CreateImport extends Command
return 1;
}
/** @var UserRepositoryInterface $userRepository */
- $userRepository = app(UserRepositoryInterface::class);
- $file = $this->argument('file');
- $configuration = $this->argument('configuration');
- $user = $userRepository->findNull((int)$this->option('user'));
- $cwd = getcwd();
- $type = strtolower($this->option('type'));
+ $userRepository = app(UserRepositoryInterface::class);
+ $file = (string)$this->argument('file');
+ $configuration = (string)$this->argument('configuration');
+ $user = $userRepository->findNull((int)$this->option('user'));
+ $cwd = getcwd();
+ $type = strtolower((string)$this->option('type'));
+ $provider = strtolower((string)$this->option('provider'));
+ $configurationData = [];
if (!$this->validArguments()) {
$this->errorLine('Invalid arguments.');
return 1;
}
+ if (\strlen($configuration) > 0) {
+ $configurationData = json_decode(file_get_contents($configuration), true);
+ if (null === $configurationData) {
+ $this->errorLine(sprintf('Firefly III cannot read the contents of configuration file "%s" (working directory: "%s").', $configuration, $cwd));
- $configurationData = json_decode(file_get_contents($configuration), true);
- if (null === $configurationData) {
- $this->errorLine(sprintf('Firefly III cannot read the contents of configuration file "%s" (working directory: "%s").', $configuration, $cwd));
-
- return 1;
+ return 1;
+ }
}
+
$this->infoLine(sprintf('Going to create a job to import file: %s', $file));
$this->infoLine(sprintf('Using configuration file: %s', $configuration));
$this->infoLine(sprintf('Import into user: #%d (%s)', $user->id, $user->email));
- $this->infoLine(sprintf('Type of import: %s', $type));
+ $this->infoLine(sprintf('Type of import: %s', $provider));
/** @var ImportJobRepositoryInterface $jobRepository */
$jobRepository = app(ImportJobRepositoryInterface::class);
$jobRepository->setUser($user);
- $job = $jobRepository->create($type);
- $this->infoLine(sprintf('Created job "%s"', $job->key));
+ $importJob = $jobRepository->create($provider);
+ $this->infoLine(sprintf('Created job "%s"', $importJob->key));
- /** @var EncryptService $service */
- $service = app(EncryptService::class);
- $service->encrypt($file, $job->key);
-
- $this->infoLine('Stored import data...');
-
- $jobRepository->setConfiguration($job, $configurationData);
- $jobRepository->updateStatus($job, 'configured');
- $this->infoLine('Stored configuration...');
-
- if (true === $this->option('start')) {
- $this->infoLine('The import will start in a moment. This process is not visible...');
- Log::debug('Go for import!');
-
- // normally would refer to other firefly:start-import but that doesn't seem to work all to well...
-
- // start the actual routine:
- $type = 'csv' === $job->file_type ? 'file' : $job->file_type;
- $key = sprintf('import.routine.%s', $type);
- $className = config($key);
- if (null === $className || !class_exists($className)) {
- throw new FireflyException(sprintf('Cannot find import routine class for job of type "%s".', $type)); // @codeCoverageIgnore
+ // make sure that job has no prerequisites.
+ if ((bool)config(sprintf('import.has_prereq.%s', $provider))) {
+ // make prerequisites thing.
+ $class = (string)config(sprintf('import.prerequisites.%s', $provider));
+ if (!class_exists($class)) {
+ throw new FireflyException(sprintf('No class to handle prerequisites for "%s".', $provider)); // @codeCoverageIgnore
}
- /** @var RoutineInterface $routine */
- $routine = app($className);
- $routine->setJob($job);
- $routine->run();
+ /** @var PrerequisitesInterface $object */
+ $object = app($class);
+ $object->setUser($user);
+ if (!$object->isComplete()) {
+ $this->errorLine(sprintf('Import provider "%s" has prerequisites that can only be filled in using the browser.', $provider));
- // give feedback.
- /** @var MessageBag $error */
- foreach ($routine->getErrors() as $index => $error) {
- $this->errorLine(sprintf('Error importing line #%d: %s', $index, $error));
+ return 1;
}
- $this->infoLine(
- sprintf(
- 'The import has finished. %d transactions have been imported out of %d records.', $routine->getJournals()->count(), $routine->getLines()
- )
- );
}
+ // store file as attachment.
+ if (\strlen($file) > 0) {
+ $messages = $jobRepository->storeCLIUpload($importJob, 'import_file', $file);
+ if ($messages->count() > 0) {
+ $this->errorLine($messages->first());
+
+ return 1;
+ }
+ $this->infoLine('File content saved.');
+ }
+
+ $this->infoLine('Job configuration saved.');
+ $jobRepository->setConfiguration($importJob, $configurationData);
+ $jobRepository->setStatus($importJob, 'ready_to_run');
+
+
+ if (true === $this->option('start')) {
+ $this->infoLine('The has started. The process is not visible. Please wait.');
+ Log::debug('Go for import!');
+
+ // run it!
+ $key = sprintf('import.routine.%s', $provider);
+ $className = config($key);
+ if (null === $className || !class_exists($className)) {
+ // @codeCoverageIgnoreStart
+ $this->errorLine(sprintf('No routine for provider "%s"', $provider));
+
+ return 1;
+ // @codeCoverageIgnoreEnd
+ }
+
+ // keep repeating this call until job lands on "provider_finished"
+ $valid = ['provider_finished'];
+ $count = 0;
+ while (!\in_array($importJob->status, $valid, true) && $count < 6) {
+ Log::debug(sprintf('Now in loop #%d.', $count + 1));
+ /** @var RoutineInterface $routine */
+ $routine = app($className);
+ $routine->setImportJob($importJob);
+ try {
+ $routine->run();
+ } catch (FireflyException|Exception $e) {
+ $message = 'The import routine crashed: ' . $e->getMessage();
+ Log::error($message);
+ Log::error($e->getTraceAsString());
+
+ // set job errored out:
+ $jobRepository->setStatus($importJob, 'error');
+ $this->errorLine($message);
+
+ return 1;
+ }
+ $count++;
+ }
+ if ($importJob->status === 'provider_finished') {
+ $this->infoLine('Import has finished. Please wait for storage of data.');
+ // set job to be storing data:
+ $jobRepository->setStatus($importJob, 'storing_data');
+
+ /** @var ImportArrayStorage $storage */
+ $storage = app(ImportArrayStorage::class);
+ $storage->setImportJob($importJob);
+
+ try {
+ $storage->store();
+ } catch (FireflyException|Exception $e) {
+ $message = 'The import routine crashed: ' . $e->getMessage();
+ Log::error($message);
+ Log::error($e->getTraceAsString());
+
+ // set job errored out:
+ $jobRepository->setStatus($importJob, 'error');
+ $this->errorLine($message);
+
+ return 1;
+ }
+ // set storage to be finished:
+ $jobRepository->setStatus($importJob, 'storage_finished');
+ }
+
+ // give feedback:
+ $this->infoLine('Job has finished.');
+ if (null !== $importJob->tag) {
+ $this->infoLine(sprintf('%d transaction(s) have been imported.', $importJob->tag->transactionJournals->count()));
+ $this->infoLine(sprintf('You can find your transactions under tag "%s"', $importJob->tag->tag));
+ }
+
+ if (null === $importJob->tag) {
+ $this->errorLine('No transactions have been imported :(.');
+ }
+ if (\count($importJob->errors) > 0) {
+ $this->infoLine(sprintf('%d error(s) occurred:', \count($importJob->errors)));
+ foreach ($importJob->errors as $err) {
+ $this->errorLine('- ' . $err);
+ }
+ }
+ }
// clear cache for user:
Preferences::setForUser($user, 'lastActivity', microtime());
@@ -185,20 +265,28 @@ class CreateImport extends Command
$cwd = getcwd();
$validTypes = config('import.options.file.import_formats');
$type = strtolower($this->option('type'));
+ $provider = strtolower($this->option('provider'));
+ $enabled = (bool)config(sprintf('import.enabled.%s', $provider));
- if (!\in_array($type, $validTypes, true)) {
+ if (false === $enabled) {
+ $this->errorLine(sprintf('Provider "%s" is not enabled.', $provider));
+
+ return false;
+ }
+
+ if ($provider === 'file' && !\in_array($type, $validTypes, true)) {
$this->errorLine(sprintf('Cannot import file of type "%s"', $type));
return false;
}
- if (!file_exists($file)) {
+ if ($provider === 'file' && !file_exists($file)) {
$this->errorLine(sprintf('Firefly III cannot find file "%s" (working directory: "%s").', $file, $cwd));
return false;
}
- if (!file_exists($configuration)) {
+ if ($provider === 'file' && !file_exists($configuration)) {
$this->errorLine(sprintf('Firefly III cannot find configuration file "%s" (working directory: "%s").', $configuration, $cwd));
return false;
diff --git a/app/Console/Commands/DecryptAttachment.php b/app/Console/Commands/DecryptAttachment.php
index baf2414ba5..dca003e8b9 100644
--- a/app/Console/Commands/DecryptAttachment.php
+++ b/app/Console/Commands/DecryptAttachment.php
@@ -1,8 +1,8 @@
.
*/
+declare(strict_types=1);
+
namespace FireflyIII\Console\Commands;
use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface;
diff --git a/app/Console/Commands/EncryptFile.php b/app/Console/Commands/EncryptFile.php
index 0e787860e7..d074897c23 100644
--- a/app/Console/Commands/EncryptFile.php
+++ b/app/Console/Commands/EncryptFile.php
@@ -1,8 +1,8 @@
.
*/
+declare(strict_types=1);
+
namespace FireflyIII\Console\Commands;
use FireflyIII\Exceptions\FireflyException;
diff --git a/app/Console/Commands/Import.php b/app/Console/Commands/Import.php
index 9a12e5988f..25ec3be10a 100644
--- a/app/Console/Commands/Import.php
+++ b/app/Console/Commands/Import.php
@@ -1,8 +1,8 @@
.
*/
+declare(strict_types=1);
+
namespace FireflyIII\Console\Commands;
use FireflyIII\Exceptions\FireflyException;
diff --git a/app/Console/Commands/ScanAttachments.php b/app/Console/Commands/ScanAttachments.php
index e30727488e..b23f82b1ce 100644
--- a/app/Console/Commands/ScanAttachments.php
+++ b/app/Console/Commands/ScanAttachments.php
@@ -1,8 +1,8 @@
.
*/
+declare(strict_types=1);
+
namespace FireflyIII\Console\Commands;
use Crypt;
diff --git a/app/Console/Commands/UpgradeDatabase.php b/app/Console/Commands/UpgradeDatabase.php
index 9c3adc2536..c4f31d21d2 100644
--- a/app/Console/Commands/UpgradeDatabase.php
+++ b/app/Console/Commands/UpgradeDatabase.php
@@ -1,8 +1,8 @@
.
*/
+declare(strict_types=1);
+
namespace FireflyIII\Console\Commands;
use DB;
@@ -159,28 +161,41 @@ class UpgradeDatabase extends Command
'order' => 2,
]
);
-
- // add triggers for amounts:
- RuleTrigger::create(
- [
- 'rule_id' => $rule->id,
- 'trigger_type' => 'amount_less',
- 'trigger_value' => round($bill->amount_max, $currency->decimal_places),
- 'active' => 1,
- 'stop_processing' => 0,
- 'order' => 3,
- ]
- );
- RuleTrigger::create(
- [
- 'rule_id' => $rule->id,
- 'trigger_type' => 'amount_more',
- 'trigger_value' => round($bill->amount_min, $currency->decimal_places),
- 'active' => 1,
- 'stop_processing' => 0,
- 'order' => 4,
- ]
- );
+ if ($bill->amount_max !== $bill->amount_min) {
+ // add triggers for amounts:
+ RuleTrigger::create(
+ [
+ 'rule_id' => $rule->id,
+ 'trigger_type' => 'amount_less',
+ 'trigger_value' => round($bill->amount_max, $currency->decimal_places),
+ 'active' => 1,
+ 'stop_processing' => 0,
+ 'order' => 3,
+ ]
+ );
+ RuleTrigger::create(
+ [
+ 'rule_id' => $rule->id,
+ 'trigger_type' => 'amount_more',
+ 'trigger_value' => round($bill->amount_min, $currency->decimal_places),
+ 'active' => 1,
+ 'stop_processing' => 0,
+ 'order' => 4,
+ ]
+ );
+ }
+ if($bill->amount_max === $bill->amount_min) {
+ RuleTrigger::create(
+ [
+ 'rule_id' => $rule->id,
+ 'trigger_type' => 'amount_exactly',
+ 'trigger_value' => round($bill->amount_min, $currency->decimal_places),
+ 'active' => 1,
+ 'stop_processing' => 0,
+ 'order' => 3,
+ ]
+ );
+ }
// create action
RuleAction::create(
@@ -600,12 +615,16 @@ class UpgradeDatabase extends Command
$opposing->transaction_currency_id = $currency->id;
$transaction->save();
$opposing->save();
- Log::debug(sprintf('Currency for account "%s" is %s, and currency for account "%s" is also
+ Log::debug(
+ sprintf(
+ 'Currency for account "%s" is %s, and currency for account "%s" is also
%s, so %s #%d (#%d and #%d) has been verified to be to %s exclusively.',
- $opposing->account->name, $opposingCurrency->code,
- $transaction->account->name, $transaction->transactionCurrency->code,
- $journal->transactionType->type, $journal->id,
- $transaction->id, $opposing->id, $currency->code));
+ $opposing->account->name, $opposingCurrency->code,
+ $transaction->account->name, $transaction->transactionCurrency->code,
+ $journal->transactionType->type, $journal->id,
+ $transaction->id, $opposing->id, $currency->code
+ )
+ );
return;
}
diff --git a/app/Console/Commands/UpgradeFireflyInstructions.php b/app/Console/Commands/UpgradeFireflyInstructions.php
index a79e62f05f..7924e609a0 100644
--- a/app/Console/Commands/UpgradeFireflyInstructions.php
+++ b/app/Console/Commands/UpgradeFireflyInstructions.php
@@ -1,8 +1,8 @@
.
*/
+declare(strict_types=1);
+
namespace FireflyIII\Console\Commands;
use Illuminate\Console\Command;
diff --git a/app/Console/Commands/UseEncryption.php b/app/Console/Commands/UseEncryption.php
index e9cbde4aed..e89aff9281 100644
--- a/app/Console/Commands/UseEncryption.php
+++ b/app/Console/Commands/UseEncryption.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
namespace FireflyIII\Console\Commands;
use Illuminate\Console\Command;
diff --git a/app/Console/Commands/VerifiesAccessToken.php b/app/Console/Commands/VerifiesAccessToken.php
index da3225a045..c03d456b53 100644
--- a/app/Console/Commands/VerifiesAccessToken.php
+++ b/app/Console/Commands/VerifiesAccessToken.php
@@ -1,8 +1,8 @@
.
*/
+declare(strict_types=1);
+
namespace FireflyIII\Console\Commands;
use FireflyIII\Repositories\User\UserRepositoryInterface;
diff --git a/app/Console/Commands/VerifyDatabase.php b/app/Console/Commands/VerifyDatabase.php
index 8db87ad4dc..08ec12f3df 100644
--- a/app/Console/Commands/VerifyDatabase.php
+++ b/app/Console/Commands/VerifyDatabase.php
@@ -1,8 +1,8 @@
.
*/
+declare(strict_types=1);
+
namespace FireflyIII\Console\Commands;
use Crypt;
diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php
index 5a16876766..3f24caad90 100644
--- a/app/Console/Kernel.php
+++ b/app/Console/Kernel.php
@@ -1,8 +1,8 @@
.
*/
+declare(strict_types=1);
+
namespace FireflyIII\Console;
use Illuminate\Console\Scheduling\Schedule;
diff --git a/app/Events/AdminRequestedTestMessage.php b/app/Events/AdminRequestedTestMessage.php
index 54858f2000..7198811a0c 100644
--- a/app/Events/AdminRequestedTestMessage.php
+++ b/app/Events/AdminRequestedTestMessage.php
@@ -1,8 +1,8 @@
.
*/
+declare(strict_types=1);
+
namespace FireflyIII\Events;
use FireflyIII\User;
diff --git a/app/Events/Event.php b/app/Events/Event.php
index 490238246a..41b3b0437c 100644
--- a/app/Events/Event.php
+++ b/app/Events/Event.php
@@ -1,8 +1,8 @@
.
*/
+declare(strict_types=1);
+
namespace FireflyIII\Events;
/**
diff --git a/app/Events/RegisteredUser.php b/app/Events/RegisteredUser.php
index 8296bcdec5..053d0b24c5 100644
--- a/app/Events/RegisteredUser.php
+++ b/app/Events/RegisteredUser.php
@@ -1,8 +1,8 @@
.
*/
+declare(strict_types=1);
+
namespace FireflyIII\Events;
use FireflyIII\User;
diff --git a/app/Events/RequestedNewPassword.php b/app/Events/RequestedNewPassword.php
index 566aadeed5..422cc19872 100644
--- a/app/Events/RequestedNewPassword.php
+++ b/app/Events/RequestedNewPassword.php
@@ -1,8 +1,8 @@
.
*/
+declare(strict_types=1);
+
namespace FireflyIII\Events;
use FireflyIII\User;
diff --git a/app/Events/RequestedVersionCheckStatus.php b/app/Events/RequestedVersionCheckStatus.php
index 1147c7cea4..6173b031af 100644
--- a/app/Events/RequestedVersionCheckStatus.php
+++ b/app/Events/RequestedVersionCheckStatus.php
@@ -1,8 +1,8 @@
.
*/
+declare(strict_types=1);
namespace FireflyIII\Events;
diff --git a/app/Events/StoredTransactionJournal.php b/app/Events/StoredTransactionJournal.php
index 2d57502558..4db12b1b35 100644
--- a/app/Events/StoredTransactionJournal.php
+++ b/app/Events/StoredTransactionJournal.php
@@ -1,8 +1,8 @@
.
*/
+declare(strict_types=1);
+
namespace FireflyIII\Events;
use FireflyIII\Models\TransactionJournal;
diff --git a/app/Events/UpdatedTransactionJournal.php b/app/Events/UpdatedTransactionJournal.php
index c8b08ddaa8..5c9c7f7a9b 100644
--- a/app/Events/UpdatedTransactionJournal.php
+++ b/app/Events/UpdatedTransactionJournal.php
@@ -1,8 +1,8 @@
.
*/
+declare(strict_types=1);
+
namespace FireflyIII\Events;
use FireflyIII\Models\TransactionJournal;
diff --git a/app/Events/UserChangedEmail.php b/app/Events/UserChangedEmail.php
index 577fcd5c86..2c2d9d8580 100644
--- a/app/Events/UserChangedEmail.php
+++ b/app/Events/UserChangedEmail.php
@@ -1,8 +1,8 @@
.
*/
+declare(strict_types=1);
+
namespace FireflyIII\Events;
use FireflyIII\User;
diff --git a/app/Exceptions/FireflyException.php b/app/Exceptions/FireflyException.php
index 2dddf3e3c7..16c24f25aa 100644
--- a/app/Exceptions/FireflyException.php
+++ b/app/Exceptions/FireflyException.php
@@ -1,8 +1,8 @@
.
*/
+declare(strict_types=1);
+
namespace FireflyIII\Exceptions;
use Exception;
diff --git a/app/Exceptions/Handler.php b/app/Exceptions/Handler.php
index 9bcf356980..d66d42a274 100644
--- a/app/Exceptions/Handler.php
+++ b/app/Exceptions/Handler.php
@@ -1,8 +1,8 @@
.
*/
+declare(strict_types=1);
+
namespace FireflyIII\Exceptions;
use ErrorException;
@@ -28,6 +30,7 @@ use FireflyIII\Jobs\MailError;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Validation\ValidationException;
+use League\OAuth2\Server\Exception\OAuthServerException;
use Request;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
@@ -79,6 +82,11 @@ class Handler extends ExceptionHandler
return response()->json(['message' => 'Unauthenticated', 'exception' => 'AuthenticationException'], 401);
}
+ if ($exception instanceof OAuthServerException && $request->expectsJson()) {
+ // somehow Laravel handler does not catch this:
+ return response()->json(['message' => $exception->getMessage(), 'exception' => 'OAuthServerException'], 401);
+ }
+
if ($request->expectsJson()) {
$isDebug = config('app.debug', false);
if ($isDebug) {
@@ -96,7 +104,7 @@ class Handler extends ExceptionHandler
return response()->json(['message' => 'Internal Firefly III Exception. See log files.', 'exception' => \get_class($exception)], 500);
}
- if ($exception instanceof FireflyException || $exception instanceof ErrorException) {
+ if ($exception instanceof FireflyException || $exception instanceof ErrorException || $exception instanceof OAuthServerException) {
$isDebug = env('APP_DEBUG', false);
return response()->view('errors.FireflyException', ['exception' => $exception, 'debug' => $isDebug], 500);
@@ -120,8 +128,25 @@ class Handler extends ExceptionHandler
*/
public function report(Exception $exception)
{
+
$doMailError = env('SEND_ERROR_MESSAGE', true);
- if (($exception instanceof FireflyException || $exception instanceof ErrorException) && $doMailError) {
+ if (
+ // if the user wants us to mail:
+ $doMailError === true &&
+ ((
+ // and if is one of these error instances
+ $exception instanceof FireflyException
+ || $exception instanceof ErrorException
+ || $exception instanceof OAuthServerException
+
+ )
+ || (
+ // or this one, but it's a JSON exception.
+ $exception instanceof AuthenticationException
+ && Request::expectsJson() === true
+ ))
+ ) {
+ // then, send email
$userData = [
'id' => 0,
'email' => 'unknown@example.com',
@@ -139,6 +164,9 @@ class Handler extends ExceptionHandler
'line' => $exception->getLine(),
'code' => $exception->getCode(),
'version' => config('firefly.version'),
+ 'url' => Request::fullUrl(),
+ 'userAgent' => Request::userAgent(),
+ 'json' => Request::acceptsJson(),
];
// create job that will mail.
diff --git a/app/Exceptions/NotImplementedException.php b/app/Exceptions/NotImplementedException.php
index e05cccd6fe..7254d56d34 100644
--- a/app/Exceptions/NotImplementedException.php
+++ b/app/Exceptions/NotImplementedException.php
@@ -1,8 +1,8 @@
.
*/
+declare(strict_types=1);
+
namespace FireflyIII\Exceptions;
/**
diff --git a/app/Exceptions/ValidationException.php b/app/Exceptions/ValidationException.php
index e0443c126e..602b4df9b0 100644
--- a/app/Exceptions/ValidationException.php
+++ b/app/Exceptions/ValidationException.php
@@ -1,8 +1,8 @@
.
*/
+declare(strict_types=1);
+
namespace FireflyIII\Exceptions;
/**
diff --git a/app/Export/Collector/AttachmentCollector.php b/app/Export/Collector/AttachmentCollector.php
index 5405855e3b..0db72ed3a2 100644
--- a/app/Export/Collector/AttachmentCollector.php
+++ b/app/Export/Collector/AttachmentCollector.php
@@ -1,8 +1,8 @@
.
*/
+declare(strict_types=1);
+
namespace FireflyIII\Export\Collector;
use Carbon\Carbon;
@@ -94,7 +96,8 @@ class AttachmentCollector extends BasicCollector implements CollectorInterface
*/
private function exportAttachment(Attachment $attachment): bool
{
- $file = $attachment->fileName();
+ $file = $attachment->fileName();
+ $decrypted = false;
if ($this->uploadDisk->exists($file)) {
try {
$decrypted = Crypt::decrypt($this->uploadDisk->get($file));
@@ -104,6 +107,9 @@ class AttachmentCollector extends BasicCollector implements CollectorInterface
return false;
}
}
+ if ($decrypted === false) {
+ return false;
+ }
$exportFile = $this->exportFileName($attachment);
$this->exportDisk->put($exportFile, $decrypted);
$this->getEntries()->push($exportFile);
diff --git a/app/Export/Collector/BasicCollector.php b/app/Export/Collector/BasicCollector.php
index 38b357ea0d..bc19f1f541 100644
--- a/app/Export/Collector/BasicCollector.php
+++ b/app/Export/Collector/BasicCollector.php
@@ -1,8 +1,8 @@
.
*/
+declare(strict_types=1);
+
namespace FireflyIII\Export\Collector;
use FireflyIII\Models\ExportJob;
diff --git a/app/Export/Collector/CollectorInterface.php b/app/Export/Collector/CollectorInterface.php
index 11c0f53271..bd40c82f29 100644
--- a/app/Export/Collector/CollectorInterface.php
+++ b/app/Export/Collector/CollectorInterface.php
@@ -1,8 +1,8 @@
.
*/
+declare(strict_types=1);
+
namespace FireflyIII\Export\Collector;
use FireflyIII\Models\ExportJob;
diff --git a/app/Export/Collector/UploadCollector.php b/app/Export/Collector/UploadCollector.php
index fccc32814a..dd8c71e769 100644
--- a/app/Export/Collector/UploadCollector.php
+++ b/app/Export/Collector/UploadCollector.php
@@ -1,8 +1,8 @@
.
*/
+declare(strict_types=1);
+
namespace FireflyIII\Export\Collector;
use Crypt;
diff --git a/app/Export/Entry/Entry.php b/app/Export/Entry/Entry.php
index a91b50e45f..55886a2697 100644
--- a/app/Export/Entry/Entry.php
+++ b/app/Export/Entry/Entry.php
@@ -1,8 +1,8 @@
.
*/
+declare(strict_types=1);
+
namespace FireflyIII\Export\Entry;
use FireflyIII\Models\Transaction;
diff --git a/app/Export/ExpandedProcessor.php b/app/Export/ExpandedProcessor.php
index 33db5e518b..d8ad004f9f 100644
--- a/app/Export/ExpandedProcessor.php
+++ b/app/Export/ExpandedProcessor.php
@@ -1,8 +1,8 @@
.
*/
+declare(strict_types=1);
+
namespace FireflyIII\Export;
use Crypt;
diff --git a/app/Export/Exporter/BasicExporter.php b/app/Export/Exporter/BasicExporter.php
index ee618c2bb2..02826171c2 100644
--- a/app/Export/Exporter/BasicExporter.php
+++ b/app/Export/Exporter/BasicExporter.php
@@ -1,8 +1,8 @@
.
*/
+declare(strict_types=1);
+
namespace FireflyIII\Export\Exporter;
use FireflyIII\Models\ExportJob;
diff --git a/app/Export/Exporter/CsvExporter.php b/app/Export/Exporter/CsvExporter.php
index 8eec22225c..e323b94bf9 100644
--- a/app/Export/Exporter/CsvExporter.php
+++ b/app/Export/Exporter/CsvExporter.php
@@ -1,8 +1,8 @@
.
*/
+declare(strict_types=1);
+
namespace FireflyIII\Export\Exporter;
use FireflyIII\Export\Entry\Entry;
diff --git a/app/Export/Exporter/ExporterInterface.php b/app/Export/Exporter/ExporterInterface.php
index f9c35b8d04..f10e763dab 100644
--- a/app/Export/Exporter/ExporterInterface.php
+++ b/app/Export/Exporter/ExporterInterface.php
@@ -1,8 +1,8 @@
.
*/
+declare(strict_types=1);
+
namespace FireflyIII\Export\Exporter;
use FireflyIII\Models\ExportJob;
diff --git a/app/Export/ProcessorInterface.php b/app/Export/ProcessorInterface.php
index c255eb7713..ad8745cc7c 100644
--- a/app/Export/ProcessorInterface.php
+++ b/app/Export/ProcessorInterface.php
@@ -1,8 +1,8 @@
.
*/
+declare(strict_types=1);
+
namespace FireflyIII\Export;
use Illuminate\Support\Collection;
diff --git a/app/Factory/AccountFactory.php b/app/Factory/AccountFactory.php
index 8c035c8548..81383d4143 100644
--- a/app/Factory/AccountFactory.php
+++ b/app/Factory/AccountFactory.php
@@ -1,5 +1,5 @@
.
*/
+declare(strict_types=1);
namespace FireflyIII\Factory;
diff --git a/app/Factory/AccountMetaFactory.php b/app/Factory/AccountMetaFactory.php
index c514e182f8..ba2172a30d 100644
--- a/app/Factory/AccountMetaFactory.php
+++ b/app/Factory/AccountMetaFactory.php
@@ -1,5 +1,5 @@
.
*/
+declare(strict_types=1);
namespace FireflyIII\Factory;
diff --git a/app/Factory/BillFactory.php b/app/Factory/BillFactory.php
index 28b4a3544d..94327af9ee 100644
--- a/app/Factory/BillFactory.php
+++ b/app/Factory/BillFactory.php
@@ -1,5 +1,5 @@
.
*/
+declare(strict_types=1);
namespace FireflyIII\Factory;
diff --git a/app/Factory/BudgetFactory.php b/app/Factory/BudgetFactory.php
index bd96712658..ba9315f4ec 100644
--- a/app/Factory/BudgetFactory.php
+++ b/app/Factory/BudgetFactory.php
@@ -1,5 +1,5 @@
.
*/
+declare(strict_types=1);
+
namespace FireflyIII\Factory;
diff --git a/app/Factory/CategoryFactory.php b/app/Factory/CategoryFactory.php
index 5bc20ec485..ff80a61a7b 100644
--- a/app/Factory/CategoryFactory.php
+++ b/app/Factory/CategoryFactory.php
@@ -1,5 +1,5 @@
.
*/
+declare(strict_types=1);
namespace FireflyIII\Factory;
diff --git a/app/Factory/PiggyBankEventFactory.php b/app/Factory/PiggyBankEventFactory.php
index d55ba7dc8f..d4a586ba03 100644
--- a/app/Factory/PiggyBankEventFactory.php
+++ b/app/Factory/PiggyBankEventFactory.php
@@ -1,5 +1,5 @@
.
*/
+declare(strict_types=1);
namespace FireflyIII\Factory;
diff --git a/app/Factory/PiggyBankFactory.php b/app/Factory/PiggyBankFactory.php
index 1f8ecf617d..ce398c3697 100644
--- a/app/Factory/PiggyBankFactory.php
+++ b/app/Factory/PiggyBankFactory.php
@@ -1,5 +1,5 @@
.
*/
+declare(strict_types=1);
namespace FireflyIII\Factory;
diff --git a/app/Factory/TagFactory.php b/app/Factory/TagFactory.php
index 09e9212a27..1fdd0e74a8 100644
--- a/app/Factory/TagFactory.php
+++ b/app/Factory/TagFactory.php
@@ -1,5 +1,5 @@
.
*/
+declare(strict_types=1);
namespace FireflyIII\Factory;
diff --git a/app/Factory/TransactionCurrencyFactory.php b/app/Factory/TransactionCurrencyFactory.php
index 1c95a60e7f..3cee423c42 100644
--- a/app/Factory/TransactionCurrencyFactory.php
+++ b/app/Factory/TransactionCurrencyFactory.php
@@ -1,5 +1,5 @@
.
*/
+declare(strict_types=1);
namespace FireflyIII\Factory;
@@ -68,7 +69,8 @@ class TransactionCurrencyFactory
$currencyCode = (string)$currencyCode;
$currencyId = (int)$currencyId;
- if (\strlen($currencyCode) === 0 && (int)$currencyId === 0) {
+ if ('' === $currencyCode && $currencyId === 0) {
+ Log::warning('Cannot find anything on empty currency code and empty currency ID!');
return null;
}
@@ -78,6 +80,7 @@ class TransactionCurrencyFactory
if (null !== $currency) {
return $currency;
}
+ Log::warning(sprintf('Currency ID is %d but found nothing!', $currencyId));
}
// then by code:
if (\strlen($currencyCode) > 0) {
@@ -85,7 +88,9 @@ class TransactionCurrencyFactory
if (null !== $currency) {
return $currency;
}
+ Log::warning(sprintf('Currency code is %d but found nothing!', $currencyCode));
}
+ Log::warning('Found nothing for currency.');
return null;
}
diff --git a/app/Factory/TransactionFactory.php b/app/Factory/TransactionFactory.php
index 468ff3f17e..c9c787d092 100644
--- a/app/Factory/TransactionFactory.php
+++ b/app/Factory/TransactionFactory.php
@@ -1,5 +1,5 @@
.
*/
+declare(strict_types=1);
namespace FireflyIII\Factory;
+use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionType;
use FireflyIII\Services\Internal\Support\TransactionServiceTrait;
use FireflyIII\User;
use Illuminate\Support\Collection;
+use Log;
/**
* Class TransactionFactory
@@ -45,10 +48,21 @@ class TransactionFactory
* @param array $data
*
* @return Transaction
+ * @throws FireflyException
*/
- public function create(array $data): Transaction
+ public function create(array $data): ?Transaction
{
- $currencyId = isset($data['currency']) ? $data['currency']->id : $data['currency_id'];
+ Log::debug('Start of TransactionFactory::create()');
+ $currencyId = $data['currency_id'] ?? null;
+ $currencyId = isset($data['currency']) ? $data['currency']->id : $currencyId;
+ if ('' === $data['amount']) {
+ throw new FireflyException('Amount is an empty string, which Firefly III cannot handle. Apologies.'); // @codeCoverageIgnore
+ }
+ if (null === $currencyId) {
+ throw new FireflyException('Cannot store transaction without currency information.'); // @codeCoverageIgnore
+ }
+ $data['foreign_amount'] = '' === (string)$data['foreign_amount'] ? null : $data['foreign_amount'];
+ Log::debug(sprintf('Create transaction for account #%d ("%s") with amount %s', $data['account']->id, $data['account']->name, $data['amount']));
return Transaction::create(
[
@@ -72,19 +86,23 @@ class TransactionFactory
* @param array $data
*
* @return Collection
+ * @throws FireflyException
*/
public function createPair(TransactionJournal $journal, array $data): Collection
{
+ Log::debug('Start of TransactionFactory::createPair()');
// all this data is the same for both transactions:
$currency = $this->findCurrency($data['currency_id'], $data['currency_code']);
$description = $journal->description === $data['description'] ? null : $data['description'];
// type of source account depends on journal type:
$sourceType = $this->accountType($journal, 'source');
+ Log::debug(sprintf('Expect source account to be of type %s', $sourceType));
$sourceAccount = $this->findAccount($sourceType, $data['source_id'], $data['source_name']);
// same for destination account:
$destinationType = $this->accountType($journal, 'destination');
+ Log::debug(sprintf('Expect source destination to be of type %s', $destinationType));
$destinationAccount = $this->findAccount($destinationType, $data['destination_id'], $data['destination_name']);
// first make a "negative" (source) transaction based on the data in the array.
$source = $this->create(
@@ -125,7 +143,7 @@ class TransactionFactory
}
// set budget:
- if ($journal->transactionType->type === TransactionType::TRANSFER) {
+ if ($journal->transactionType->type !== TransactionType::WITHDRAWAL) {
$data['budget_id'] = null;
$data['budget_name'] = null;
}
diff --git a/app/Factory/TransactionJournalFactory.php b/app/Factory/TransactionJournalFactory.php
index a4422b7b71..fbee73ea96 100644
--- a/app/Factory/TransactionJournalFactory.php
+++ b/app/Factory/TransactionJournalFactory.php
@@ -1,5 +1,5 @@
.
*/
+declare(strict_types=1);
namespace FireflyIII\Factory;
@@ -51,6 +52,7 @@ class TransactionJournalFactory
// store basic journal first.
$type = $this->findTransactionType($data['type']);
$defaultCurrency = app('amount')->getDefaultCurrencyByUser($this->user);
+ Log::debug(sprintf('Going to store a %s', $type->type));
$journal = TransactionJournal::create(
[
'user_id' => $data['user'],
@@ -70,8 +72,10 @@ class TransactionJournalFactory
$factory = app(TransactionFactory::class);
$factory->setUser($this->user);
+ Log::debug(sprintf('Found %d transactions in array.', \count($data['transactions'])));
/** @var array $trData */
- foreach ($data['transactions'] as $trData) {
+ foreach ($data['transactions'] as $index => $trData) {
+ Log::debug(sprintf('Now storing transaction %d of %d', $index + 1, \count($data['transactions'])));
$factory->createPair($journal, $trData);
}
$journal->completed = true;
@@ -91,7 +95,7 @@ class TransactionJournalFactory
// store date meta fields (if present):
$fields = ['sepa-cc', 'sepa-ct-op', 'sepa-ct-id', 'sepa-db', 'sepa-country', 'sepa-ep', 'sepa-ci', 'interest_date', 'book_date', 'process_date',
- 'due_date', 'payment_date', 'invoice_date', 'internal_reference', 'bunq_payment_id','importHash'];
+ 'due_date', 'payment_date', 'invoice_date', 'internal_reference', 'bunq_payment_id', 'importHash','importHashV2', 'external_id'];
foreach ($fields as $field) {
$this->storeMeta($journal, $data, $field);
diff --git a/app/Factory/TransactionJournalMetaFactory.php b/app/Factory/TransactionJournalMetaFactory.php
index 4be44a8bbe..2af8397c0a 100644
--- a/app/Factory/TransactionJournalMetaFactory.php
+++ b/app/Factory/TransactionJournalMetaFactory.php
@@ -1,5 +1,5 @@
.
*/
+declare(strict_types=1);
namespace FireflyIII\Factory;
@@ -70,6 +71,7 @@ class TransactionJournalMetaFactory
}
if (null === $entry) {
+ Log::debug(sprintf('Going to create new meta-data entry to store "%s".', $data['name']));
$entry = new TransactionJournalMeta();
$entry->transactionJournal()->associate($data['journal']);
$entry->name = $data['name'];
diff --git a/app/Factory/TransactionTypeFactory.php b/app/Factory/TransactionTypeFactory.php
index 8a36869407..03db2cbd13 100644
--- a/app/Factory/TransactionTypeFactory.php
+++ b/app/Factory/TransactionTypeFactory.php
@@ -1,5 +1,5 @@
.
*/
+declare(strict_types=1);
namespace FireflyIII\Factory;
diff --git a/app/Handlers/Events/APIEventHandler.php b/app/Handlers/Events/APIEventHandler.php
new file mode 100644
index 0000000000..64aa286420
--- /dev/null
+++ b/app/Handlers/Events/APIEventHandler.php
@@ -0,0 +1,80 @@
+.
+ */
+
+declare(strict_types=1);
+
+namespace FireflyIII\Handlers\Events;
+
+
+use Exception;
+use FireflyIII\Mail\AccessTokenCreatedMail;
+use FireflyIII\Repositories\User\UserRepositoryInterface;
+use Laravel\Passport\Events\AccessTokenCreated;
+use Laravel\Passport\Token;
+use Log;
+use Mail;
+use Request;
+use Session;
+
+/**
+ * Class APIEventHandler
+ */
+class APIEventHandler
+{
+ /**
+ * @param AccessTokenCreated $event
+ *
+ * @return bool
+ */
+ public function accessTokenCreated(AccessTokenCreated $event): bool
+ {
+ /** @var UserRepositoryInterface $repository */
+ $repository = app(UserRepositoryInterface::class);
+ $user = $repository->findNull((int)$event->userId);
+ if (null === $user) {
+ Log::error('Access Token generated but no user associated.');
+
+ return true;
+ }
+
+ $email = $user->email;
+ $ipAddress = Request::ip();
+
+ Log::debug(sprintf('Now in APIEventHandler::accessTokenCreated. Email is %s, IP is %s', $email, $ipAddress));
+ try {
+ Log::debug('Trying to send message...');
+ Mail::to($email)->send(new AccessTokenCreatedMail($email, $ipAddress));
+ // @codeCoverageIgnoreStart
+ } catch (Exception $e) {
+ Log::debug('Send message failed! :(');
+ Log::error($e->getMessage());
+ Log::error($e->getTraceAsString());
+ Session::flash('error', 'Possible email error: ' . $e->getMessage());
+ }
+ Log::debug('If no error above this line, message was sent.');
+
+ // @codeCoverageIgnoreEnd
+ return true;
+
+
+ }
+
+}
\ No newline at end of file
diff --git a/app/Helpers/Attachments/AttachmentHelper.php b/app/Helpers/Attachments/AttachmentHelper.php
index b4da01386b..72a00bab0c 100644
--- a/app/Helpers/Attachments/AttachmentHelper.php
+++ b/app/Helpers/Attachments/AttachmentHelper.php
@@ -24,6 +24,8 @@ namespace FireflyIII\Helpers\Attachments;
use Crypt;
use FireflyIII\Models\Attachment;
+use Illuminate\Contracts\Encryption\DecryptException;
+use Illuminate\Contracts\Filesystem\FileNotFoundException;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;
use Illuminate\Support\MessageBag;
@@ -64,6 +66,26 @@ class AttachmentHelper implements AttachmentHelperInterface
$this->uploadDisk = Storage::disk('upload');
}
+ /**
+ * @codeCoverageIgnore
+ *
+ * @param Attachment $attachment
+ *
+ * @return string
+ */
+ public function getAttachmentContent(Attachment $attachment): string
+ {
+ try {
+ $content = Crypt::decrypt($this->uploadDisk->get(sprintf('at-%d.data', $attachment->id)));
+ } catch (DecryptException|FileNotFoundException $e) {
+ Log::error(sprintf('Could not decrypt data of attachment #%d', $attachment->id));
+
+ return '';
+ }
+
+ return $content;
+ }
+
/**
* @param Attachment $attachment
*
diff --git a/app/Helpers/Attachments/AttachmentHelperInterface.php b/app/Helpers/Attachments/AttachmentHelperInterface.php
index fc66698573..276d312a27 100644
--- a/app/Helpers/Attachments/AttachmentHelperInterface.php
+++ b/app/Helpers/Attachments/AttachmentHelperInterface.php
@@ -39,6 +39,13 @@ interface AttachmentHelperInterface
*/
public function getAttachmentLocation(Attachment $attachment): string;
+ /**
+ * @param Attachment $attachment
+ *
+ * @return string
+ */
+ public function getAttachmentContent(Attachment $attachment): string;
+
/**
* @return Collection
*/
diff --git a/app/Helpers/Collector/JournalCollector.php b/app/Helpers/Collector/JournalCollector.php
index 79e69f923c..b2eb90dc1a 100644
--- a/app/Helpers/Collector/JournalCollector.php
+++ b/app/Helpers/Collector/JournalCollector.php
@@ -32,6 +32,7 @@ use FireflyIII\Helpers\Filter\NegativeAmountFilter;
use FireflyIII\Helpers\Filter\OpposingAccountFilter;
use FireflyIII\Helpers\Filter\PositiveAmountFilter;
use FireflyIII\Helpers\Filter\SplitIndicatorFilter;
+use FireflyIII\Helpers\Filter\TransactionViewFilter;
use FireflyIII\Helpers\Filter\TransferFilter;
use FireflyIII\Models\AccountType;
use FireflyIII\Models\Budget;
@@ -60,6 +61,7 @@ use Steam;
*/
class JournalCollector implements JournalCollectorInterface
{
+
/** @var array */
private $accountIds = [];
/** @var int */
@@ -106,7 +108,8 @@ class JournalCollector implements JournalCollectorInterface
];
/** @var array */
private $filters = [InternalTransferFilter::class];
-
+ /** @var bool */
+ private $ignoreCache = false;
/** @var bool */
private $joinedBudget = false;
/** @var bool */
@@ -257,12 +260,15 @@ class JournalCollector implements JournalCollectorInterface
foreach ($this->filters as $filter) {
$cache->addProperty((string)$filter);
}
- if ($cache->has()) {
+ if (false === $this->ignoreCache && $cache->has()) {
Log::debug(sprintf('Return cache of query with ID "%s".', $key));
return $cache->get(); // @codeCoverageIgnore
- }
+ }
+ if (true === $this->ignoreCache) {
+ Log::debug('Ignore cache in journal collector.');
+ }
/** @var Collection $set */
$set = $this->query->get(array_values($this->fields));
@@ -315,6 +321,16 @@ class JournalCollector implements JournalCollectorInterface
return $journals;
}
+ /**
+ * @return JournalCollectorInterface
+ */
+ public function ignoreCache(): JournalCollectorInterface
+ {
+ $this->ignoreCache = true;
+
+ return $this;
+ }
+
/**
* @param string $filter
*
@@ -768,6 +784,7 @@ class JournalCollector implements JournalCollectorInterface
NegativeAmountFilter::class => new NegativeAmountFilter,
SplitIndicatorFilter::class => new SplitIndicatorFilter,
CountAttachmentsFilter::class => new CountAttachmentsFilter,
+ TransactionViewFilter::class => new TransactionViewFilter,
];
Log::debug(sprintf('Will run %d filters on the set.', \count($this->filters)));
foreach ($this->filters as $enabled) {
@@ -784,7 +801,7 @@ class JournalCollector implements JournalCollectorInterface
/**
*
*/
- private function joinBudgetTables()
+ private function joinBudgetTables(): void
{
if (!$this->joinedBudget) {
// join some extra tables:
@@ -809,7 +826,7 @@ class JournalCollector implements JournalCollectorInterface
/**
*
*/
- private function joinCategoryTables()
+ private function joinCategoryTables(): void
{
if (!$this->joinedCategory) {
// join some extra tables:
@@ -839,7 +856,7 @@ class JournalCollector implements JournalCollectorInterface
/**
*
*/
- private function joinOpposingTables()
+ private function joinOpposingTables(): void
{
if (!$this->joinedOpposing) {
Log::debug('joinedOpposing is false');
@@ -871,7 +888,7 @@ class JournalCollector implements JournalCollectorInterface
/**
*
*/
- private function joinTagTables()
+ private function joinTagTables(): void
{
if (!$this->joinedTag) {
// join some extra tables:
diff --git a/app/Helpers/Collector/JournalCollectorInterface.php b/app/Helpers/Collector/JournalCollectorInterface.php
index 1b439a748b..b710326175 100644
--- a/app/Helpers/Collector/JournalCollectorInterface.php
+++ b/app/Helpers/Collector/JournalCollectorInterface.php
@@ -78,6 +78,11 @@ interface JournalCollectorInterface
*/
public function getPaginatedJournals(): LengthAwarePaginator;
+ /**
+ * @return JournalCollectorInterface
+ */
+ public function ignoreCache(): JournalCollectorInterface;
+
/**
* @param string $filter
*
diff --git a/app/Helpers/Filter/TransactionViewFilter.php b/app/Helpers/Filter/TransactionViewFilter.php
new file mode 100644
index 0000000000..ea83a62e75
--- /dev/null
+++ b/app/Helpers/Filter/TransactionViewFilter.php
@@ -0,0 +1,80 @@
+.
+ */
+declare(strict_types=1);
+
+namespace FireflyIII\Helpers\Filter;
+
+use FireflyIII\Models\Transaction;
+use FireflyIII\Models\TransactionType;
+use Illuminate\Support\Collection;
+use Log;
+
+/**
+ * Class TransactionViewFilter.
+ *
+ * This filter removes the entry with a negative amount when it's a withdrawal
+ * And the positive amount when it's a deposit or transfer
+ *
+ * This is used in the mass-edit routine.
+ *
+ */
+class TransactionViewFilter implements FilterInterface
+{
+ /**
+ * @param Collection $set
+ *
+ * @return Collection
+ */
+ public function filter(Collection $set): Collection
+ {
+ return $set->filter(
+ function (Transaction $transaction) {
+ // remove if amount is less than zero and type is withdrawal.
+ if ($transaction->transaction_type_type === TransactionType::WITHDRAWAL && 1 === bccomp($transaction->transaction_amount, '0')) {
+ Log::debug(
+ sprintf(
+ 'Filtered #%d because amount is %f and type is %s.', $transaction->id, $transaction->transaction_amount,
+ $transaction->transaction_type_type
+ )
+ );
+
+ return null;
+ }
+
+ if ($transaction->transaction_type_type === TransactionType::DEPOSIT && -1 === bccomp($transaction->transaction_amount, '0')) {
+ Log::debug(
+ sprintf(
+ 'Filtered #%d because amount is %f and type is %s.', $transaction->id, $transaction->transaction_amount,
+ $transaction->transaction_type_type
+ )
+ );
+
+ return null;
+ }
+ Log::debug(
+ sprintf('#%d: amount is %f and type is %s.', $transaction->id, $transaction->transaction_amount, $transaction->transaction_type_type)
+ );
+
+ return $transaction;
+ }
+ );
+ }
+}
diff --git a/app/Http/Controllers/AccountController.php b/app/Http/Controllers/AccountController.php
index 4c15c0406b..db68a5c841 100644
--- a/app/Http/Controllers/AccountController.php
+++ b/app/Http/Controllers/AccountController.php
@@ -210,18 +210,7 @@ class AccountController extends Controller
$request->session()->flash('preFilled', $preFilled);
- return view(
- 'accounts.edit',
- compact(
- 'account',
- 'currency',
- 'subTitle',
- 'subTitleIcon',
- 'what',
- 'roles',
- 'preFilled'
- )
- );
+ return view('accounts.edit', compact('account', 'currency', 'subTitle', 'subTitleIcon', 'what', 'roles', 'preFilled'));
}
/**
@@ -297,8 +286,10 @@ class AccountController extends Controller
throw new FireflyException('End is after start!'); // @codeCoverageIgnore
}
+
+ $what = config(sprintf('firefly.shortNamesByFullName.%s', $account->accountType->type)); // used for menu
$today = new Carbon;
- $subTitleIcon = config('firefly.subIconsByIdentifier.' . $account->accountType->type);
+ $subTitleIcon = config(sprintf('firefly.subIconsByIdentifier.%s', $account->accountType->type));
$page = (int)$request->get('page');
$pageSize = (int)Preferences::get('listPageSize', 50)->data;
$currencyId = (int)$this->repository->getMetaValue($account, 'currency_id');
@@ -320,7 +311,7 @@ class AccountController extends Controller
return view(
'accounts.show',
- compact('account', 'showAll', 'currency', 'today', 'periods', 'subTitleIcon', 'transactions', 'subTitle', 'start', 'end', 'chartUri')
+ compact('account', 'showAll', 'what', 'currency', 'today', 'periods', 'subTitleIcon', 'transactions', 'subTitle', 'start', 'end', 'chartUri')
);
}
@@ -338,7 +329,7 @@ class AccountController extends Controller
public function showAll(Request $request, Account $account)
{
if (AccountType::INITIAL_BALANCE === $account->accountType->type) {
- return $this->redirectToOriginalAccount($account);
+ return $this->redirectToOriginalAccount($account); // @codeCoverageIgnore
}
$end = new Carbon;
$today = new Carbon;
diff --git a/app/Http/Controllers/BillController.php b/app/Http/Controllers/BillController.php
index 2e0d35969b..bbb5a96234 100644
--- a/app/Http/Controllers/BillController.php
+++ b/app/Http/Controllers/BillController.php
@@ -22,14 +22,11 @@ declare(strict_types=1);
namespace FireflyIII\Http\Controllers;
-use ExpandedForm;
use FireflyIII\Helpers\Attachments\AttachmentHelperInterface;
use FireflyIII\Helpers\Collector\JournalCollectorInterface;
use FireflyIII\Http\Requests\BillFormRequest;
use FireflyIII\Models\Bill;
-use FireflyIII\Models\Note;
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
-use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\Repositories\RuleGroup\RuleGroupRepositoryInterface;
use FireflyIII\TransactionRules\TransactionMatcher;
use FireflyIII\Transformers\BillTransformer;
@@ -50,6 +47,10 @@ class BillController extends Controller
{
/** @var AttachmentHelperInterface Helper for attachments. */
private $attachments;
+ /** @var BillRepositoryInterface */
+ private $billRepository;
+ /** @var RuleGroupRepositoryInterface */
+ private $ruleGroupRepos;
/**
*
@@ -67,7 +68,9 @@ class BillController extends Controller
function ($request, $next) {
app('view')->share('title', trans('firefly.bills'));
app('view')->share('mainTitleIcon', 'fa-calendar-o');
- $this->attachments = app(AttachmentHelperInterface::class);
+ $this->attachments = app(AttachmentHelperInterface::class);
+ $this->billRepository = app(BillRepositoryInterface::class);
+ $this->ruleGroupRepos = app(RuleGroupRepositoryInterface::class);
return $next($request);
}
@@ -75,21 +78,20 @@ class BillController extends Controller
}
/**
- * @param Request $request
- *
- * @param CurrencyRepositoryInterface $repository
+ * @param Request $request
*
* @return View
*/
- public function create(Request $request, CurrencyRepositoryInterface $repository)
+ public function create(Request $request)
{
$periods = [];
- foreach (config('firefly.bill_periods') as $current) {
+ /** @var array $billPeriods */
+ $billPeriods = config('firefly.bill_periods');
+ foreach ($billPeriods as $current) {
$periods[$current] = strtolower((string)trans('firefly.repeat_freq_' . $current));
}
$subTitle = trans('firefly.create_new_bill');
$defaultCurrency = app('amount')->getDefaultCurrency();
- $currencies = ExpandedForm::makeSelectList($repository->get());
// put previous url in session if not redirect from store (not "create another").
if (true !== session('bills.create.fromStore')) {
@@ -97,7 +99,7 @@ class BillController extends Controller
}
$request->session()->forget('bills.create.fromStore');
- return view('bills.create', compact('periods', 'subTitle', 'currencies', 'defaultCurrency'));
+ return view('bills.create', compact('periods', 'subTitle', 'defaultCurrency'));
}
/**
@@ -115,16 +117,15 @@ class BillController extends Controller
}
/**
- * @param Request $request
- * @param BillRepositoryInterface $repository
- * @param Bill $bill
+ * @param Request $request
+ * @param Bill $bill
*
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*/
- public function destroy(Request $request, BillRepositoryInterface $repository, Bill $bill)
+ public function destroy(Request $request, Bill $bill)
{
$name = $bill->name;
- $repository->destroy($bill);
+ $this->billRepository->destroy($bill);
$request->session()->flash('success', (string)trans('firefly.deleted_bill', ['name' => $name]));
Preferences::mark();
@@ -133,18 +134,21 @@ class BillController extends Controller
}
/**
- * @param Request $request
- * @param CurrencyRepositoryInterface $repository
- * @param Bill $bill
+ * @param Request $request
+ * @param Bill $bill
*
* @return View
*/
- public function edit(Request $request, CurrencyRepositoryInterface $repository, Bill $bill)
+ public function edit(Request $request, Bill $bill)
{
$periods = [];
- foreach (config('firefly.bill_periods') as $current) {
+ /** @var array $billPeriods */
+ $billPeriods = config('firefly.bill_periods');
+
+ foreach ($billPeriods as $current) {
$periods[$current] = trans('firefly.' . $current);
}
+
$subTitle = trans('firefly.edit_bill', ['name' => $bill->name]);
// put previous url in session if not redirect from store (not "return_to_edit").
@@ -156,36 +160,28 @@ class BillController extends Controller
$bill->amount_min = round($bill->amount_min, $currency->decimal_places);
$bill->amount_max = round($bill->amount_max, $currency->decimal_places);
$defaultCurrency = app('amount')->getDefaultCurrency();
- $currencies = ExpandedForm::makeSelectList($repository->get());
$preFilled = [
- 'notes' => '',
+ 'notes' => $this->billRepository->getNoteText($bill),
+ 'transaction_currency_id' => $bill->transaction_currency_id,
+ 'active' => $bill->active,
];
- /** @var Note $note */
- $note = $bill->notes()->first();
- if (null !== $note) {
- $preFilled['notes'] = $note->text;
- }
-
$request->session()->flash('preFilled', $preFilled);
-
$request->session()->forget('bills.edit.fromUpdate');
- return view('bills.edit', compact('subTitle', 'periods', 'bill', 'defaultCurrency', 'currencies'));
+ return view('bills.edit', compact('subTitle', 'periods', 'bill', 'defaultCurrency', 'preFilled'));
}
/**
- * @param BillRepositoryInterface $repository
- *
* @return View
*/
- public function index(BillRepositoryInterface $repository)
+ public function index()
{
$start = session('start');
$end = session('end');
$pageSize = (int)Preferences::get('listPageSize', 50)->data;
- $paginator = $repository->getPaginator($pageSize);
+ $paginator = $this->billRepository->getPaginator($pageSize);
$parameters = new ParameterBag();
$parameters->set('start', $start);
$parameters->set('end', $end);
@@ -203,7 +199,7 @@ class BillController extends Controller
);
// add info about rules:
- $rules = $repository->getRulesForBills($paginator->getCollection());
+ $rules = $this->billRepository->getRulesForBills($paginator->getCollection());
$bills = $bills->map(
function (array $bill) use ($rules) {
$bill['rules'] = $rules[$bill['id']] ?? [];
@@ -218,21 +214,20 @@ class BillController extends Controller
}
/**
- * @param Request $request
- * @param BillRepositoryInterface $repository
- * @param Bill $bill
+ * @param Request $request
+ * @param Bill $bill
*
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
* @throws \FireflyIII\Exceptions\FireflyException
*/
- public function rescan(Request $request, BillRepositoryInterface $repository, Bill $bill)
+ public function rescan(Request $request, Bill $bill)
{
if (0 === (int)$bill->active) {
$request->session()->flash('warning', (string)trans('firefly.cannot_scan_inactive_bill'));
return redirect(URL::previous());
}
- $set = $repository->getRulesForBill($bill);
+ $set = $this->billRepository->getRulesForBill($bill);
$total = 0;
foreach ($set as $rule) {
// simply fire off all rules?
@@ -243,7 +238,7 @@ class BillController extends Controller
$matcher->setRule($rule);
$matchingTransactions = $matcher->findTransactionsByRule();
$total += $matchingTransactions->count();
- $repository->linkCollectionToBill($bill, $matchingTransactions);
+ $this->billRepository->linkCollectionToBill($bill, $matchingTransactions);
}
@@ -254,24 +249,23 @@ class BillController extends Controller
}
/**
- * @param Request $request
- * @param BillRepositoryInterface $repository
- * @param Bill $bill
+ * @param Request $request
+ * @param Bill $bill
*
* @return View
*/
- public function show(Request $request, BillRepositoryInterface $repository, Bill $bill)
+ public function show(Request $request, Bill $bill)
{
// add info about rules:
- $rules = $repository->getRulesForBill($bill);
+ $rules = $this->billRepository->getRulesForBill($bill);
$subTitle = $bill->name;
$start = session('start');
$end = session('end');
$year = $start->year;
$page = (int)$request->get('page');
$pageSize = (int)Preferences::get('listPageSize', 50)->data;
- $yearAverage = $repository->getYearAverage($bill, $start);
- $overallAverage = $repository->getOverallAverage($bill);
+ $yearAverage = $this->billRepository->getYearAverage($bill, $start);
+ $overallAverage = $this->billRepository->getOverallAverage($bill);
$manager = new Manager();
$manager->setSerializer(new DataArraySerializer());
$manager->parseIncludes(['attachments', 'notes']);
@@ -296,16 +290,14 @@ class BillController extends Controller
}
/**
- * @param BillFormRequest $request
- * @param BillRepositoryInterface $repository
+ * @param BillFormRequest $request
*
- * @param RuleGroupRepositoryInterface $ruleGroupRepository
* @return \Illuminate\Http\RedirectResponse
*/
- public function store(BillFormRequest $request, BillRepositoryInterface $repository, RuleGroupRepositoryInterface $ruleGroupRepository)
+ public function store(BillFormRequest $request)
{
$billData = $request->getBillData();
- $bill = $repository->store($billData);
+ $bill = $this->billRepository->store($billData);
if (null === $bill) {
$request->session()->flash('error', (string)trans('firefly.bill_store_error'));
@@ -330,16 +322,16 @@ class BillController extends Controller
}
// find first rule group, or create one:
- $count = $ruleGroupRepository->count();
+ $count = $this->ruleGroupRepos->count();
if ($count === 0) {
$data = [
'title' => (string)trans('firefly.rulegroup_for_bills_title'),
'description' => (string)trans('firefly.rulegroup_for_bills_description'),
];
- $group = $ruleGroupRepository->store($data);
+ $group = $this->ruleGroupRepos->store($data);
}
if ($count > 0) {
- $group = $ruleGroupRepository->getActiveGroups(auth()->user())->first();
+ $group = $this->ruleGroupRepos->getActiveGroups(auth()->user())->first();
}
// redirect to page that will create a new rule.
@@ -349,16 +341,15 @@ class BillController extends Controller
}
/**
- * @param BillFormRequest $request
- * @param BillRepositoryInterface $repository
- * @param Bill $bill
+ * @param BillFormRequest $request
+ * @param Bill $bill
*
* @return \Illuminate\Http\RedirectResponse
*/
- public function update(BillFormRequest $request, BillRepositoryInterface $repository, Bill $bill)
+ public function update(BillFormRequest $request, Bill $bill)
{
$billData = $request->getBillData();
- $bill = $repository->update($bill, $billData);
+ $bill = $this->billRepository->update($bill, $billData);
$request->session()->flash('success', (string)trans('firefly.updated_bill', ['name' => $bill->name]));
Preferences::mark();
diff --git a/app/Http/Controllers/BudgetController.php b/app/Http/Controllers/BudgetController.php
index 3ab8154910..ed199483d5 100644
--- a/app/Http/Controllers/BudgetController.php
+++ b/app/Http/Controllers/BudgetController.php
@@ -87,6 +87,8 @@ class BudgetController extends Controller
$budgetLimit = $this->repository->updateLimitAmount($budget, $start, $end, $amount);
$largeDiff = false;
$warnText = '';
+ $days = 0;
+ $daysInMonth = 0;
if (0 === bccomp($amount, '0')) {
$budgetLimit = null;
}
@@ -94,13 +96,17 @@ class BudgetController extends Controller
// if today is between start and end, use the diff in days between end and today (days left)
// otherwise, use diff between start and end.
$today = new Carbon;
+ Log::debug(sprintf('Start is %s, end is %s, today is %s', $start->format('Y-m-d'), $end->format('Y-m-d'),$today->format('Y-m-d')));
if ($today->gte($start) && $today->lte($end)) {
- $days = $end->diffInDays($today);
+ $days = $end->diffInDays($today);
+ $daysInMonth = $start->diffInDays($today);
}
if ($today->lte($start) || $today->gte($end)) {
- $days = $start->diffInDays($end);
+ $days = $start->diffInDays($end);
+ $daysInMonth = $start->diffInDays($end);
}
- $days = $days === 0 ? 1 : $days;
+ $days = $days === 0 ? 1 : $days;
+ $daysInMonth = $daysInMonth === 0 ? 1 : $daysInMonth;
// calculate left in budget:
$spent = $repository->spentInPeriod(new Collection([$budget]), new Collection, $start, $end);
@@ -146,6 +152,7 @@ class BudgetController extends Controller
'large_diff' => $largeDiff,
'left_per_day' => $leftPerDay,
'warn_text' => $warnText,
+ 'daysInMonth' => $daysInMonth,
]
);
@@ -229,22 +236,13 @@ class BudgetController extends Controller
*/
public function index(Request $request, string $moment = null)
{
- $range = Preferences::get('viewRange', '1M')->data;
- $start = session('start', new Carbon);
- $end = session('end', new Carbon);
- $page = 0 === (int)$request->get('page') ? 1 : (int)$request->get('page');
- $pageSize = (int)Preferences::get('listPageSize', 50)->data;
-
- // if today is between start and end, use the diff in days between end and today (days left)
- // otherwise, use diff between start and end.
- $today = new Carbon;
- if ($today->gte($start) && $today->lte($end)) {
- $days = $end->diffInDays($today);
- }
- if ($today->lte($start) || $today->gte($end)) {
- $days = $start->diffInDays($end);
- }
- $days = $days === 0 ? 1 : $days;
+ $range = Preferences::get('viewRange', '1M')->data;
+ $start = session('start', new Carbon);
+ $end = session('end', new Carbon);
+ $page = 0 === (int)$request->get('page') ? 1 : (int)$request->get('page');
+ $pageSize = (int)Preferences::get('listPageSize', 50)->data;
+ $days = 0;
+ $daysInMonth = 0;
// make date if present:
if (null !== $moment || '' !== (string)$moment) {
@@ -256,6 +254,22 @@ class BudgetController extends Controller
Log::debug('start and end are already defined.');
}
}
+
+ // if today is between start and end, use the diff in days between end and today (days left)
+ // otherwise, use diff between start and end.
+ $today = new Carbon;
+ if ($today->gte($start) && $today->lte($end)) {
+ $days = $end->diffInDays($today);
+ $daysInMonth = $start->diffInDays($today);
+ }
+ if ($today->lte($start) || $today->gte($end)) {
+ $days = $start->diffInDays($end);
+ $daysInMonth = $start->diffInDays($end);
+ }
+ $days = $days === 0 ? 1 : $days;
+ $daysInMonth = $daysInMonth === 0 ? 1 : $daysInMonth;
+
+
$next = clone $end;
$next->addDay();
$prev = clone $start;
@@ -312,7 +326,7 @@ class BudgetController extends Controller
return view(
'budgets.index', compact(
'available', 'currentMonth', 'next', 'nextText', 'prev', 'allBudgets', 'prevText', 'periodStart', 'periodEnd', 'days', 'page',
- 'budgetInformation',
+ 'budgetInformation', 'daysInMonth',
'inactive', 'budgets', 'spent', 'budgeted', 'previousLoop', 'nextLoop', 'start', 'end'
)
);
diff --git a/app/Http/Controllers/DebugController.php b/app/Http/Controllers/DebugController.php
index 4a56acf427..11f52acf5c 100644
--- a/app/Http/Controllers/DebugController.php
+++ b/app/Http/Controllers/DebugController.php
@@ -66,6 +66,7 @@ class DebugController extends Controller
$userAgent = $request->header('user-agent');
$isSandstorm = var_export(env('IS_SANDSTORM', 'unknown'), true);
$isDocker = var_export(env('IS_DOCKER', 'unknown'), true);
+ $toSandbox = var_export(env('BUNQ_USE_SANDBOX', 'unknown'), true);
$trustedProxies = env('TRUSTED_PROXIES', '(none)');
$displayErrors = ini_get('display_errors');
$errorReporting = $this->errorReporting((int)ini_get('error_reporting'));
@@ -96,40 +97,24 @@ class DebugController extends Controller
if (null !== $logFile) {
try {
$logContent = file_get_contents($logFile);
+ // @codeCoverageIgnoreStart
} catch (Exception $e) {
// don't care
Log::debug(sprintf('Could not read log file. %s', $e->getMessage()));
}
+ // @codeCoverageIgnoreEnd
}
}
}
// last few lines
- $logContent = 'Truncated from this point <----|' . substr($logContent, -4096);
+ $logContent = 'Truncated from this point <----|' . substr($logContent, -8192);
return view(
- 'debug',
- compact(
- 'phpVersion',
- 'extensions', 'localeAttempts',
- 'appEnv',
- 'appDebug',
- 'appLog',
- 'appLogLevel',
- 'now',
- 'packages',
- 'drivers',
- 'currentDriver',
- 'userAgent',
- 'displayErrors',
- 'errorReporting',
- 'phpOs',
- 'interface',
- 'logContent',
- 'cacheDriver',
- 'isDocker',
- 'isSandstorm',
- 'trustedProxies'
- )
+ 'debug', compact(
+ 'phpVersion', 'extensions', 'localeAttempts', 'appEnv', 'appDebug', 'appLog', 'appLogLevel', 'now', 'packages', 'drivers', 'currentDriver',
+ 'userAgent', 'displayErrors', 'errorReporting', 'phpOs', 'interface', 'logContent', 'cacheDriver', 'isDocker', 'isSandstorm', 'trustedProxies',
+ 'toSandbox'
+ )
);
}
diff --git a/app/Http/Controllers/ExportController.php b/app/Http/Controllers/ExportController.php
index 2c19715d42..a6836ba004 100644
--- a/app/Http/Controllers/ExportController.php
+++ b/app/Http/Controllers/ExportController.php
@@ -23,12 +23,10 @@ declare(strict_types=1);
namespace FireflyIII\Http\Controllers;
use Carbon\Carbon;
-use ExpandedForm;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Export\ProcessorInterface;
use FireflyIII\Http\Middleware\IsDemoUser;
use FireflyIII\Http\Requests\ExportFormRequest;
-use FireflyIII\Models\AccountType;
use FireflyIII\Models\ExportJob;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\ExportJob\ExportJobRepositoryInterface;
@@ -107,12 +105,11 @@ class ExportController extends Controller
}
/**
- * @param AccountRepositoryInterface $repository
* @param ExportJobRepositoryInterface $jobs
*
* @return View
*/
- public function index(AccountRepositoryInterface $repository, ExportJobRepositoryInterface $jobs)
+ public function index(ExportJobRepositoryInterface $jobs)
{
// create new export job.
$job = $jobs->create();
@@ -120,15 +117,12 @@ class ExportController extends Controller
$jobs->cleanup();
// does the user have shared accounts?
- $accounts = $repository->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET]);
- $accountList = ExpandedForm::makeSelectList($accounts);
- $checked = array_keys($accountList);
$formats = array_keys(config('firefly.export_formats'));
$defaultFormat = Preferences::get('export_format', config('firefly.default_export_format'))->data;
$first = session('first')->format('Y-m-d');
$today = Carbon::create()->format('Y-m-d');
- return view('export.index', compact('job', 'checked', 'accountList', 'formats', 'defaultFormat', 'first', 'today'));
+ return view('export.index', compact('job', 'formats', 'defaultFormat', 'first', 'today'));
}
/**
diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php
index ba32b7e7ba..993d3273e5 100644
--- a/app/Http/Controllers/HomeController.php
+++ b/app/Http/Controllers/HomeController.php
@@ -133,10 +133,12 @@ class HomeController extends Controller
Log::debug('Call twig:clean...');
try {
Artisan::call('twig:clean');
+ // @codeCoverageIgnoreStart
} catch (Exception $e) {
- // dont care
+ // don't care
Log::debug('Called twig:clean.');
}
+ // @codeCoverageIgnoreEnd
Log::debug('Call view:clear...');
Artisan::call('view:clear');
Log::debug('Done! Redirecting...');
diff --git a/app/Http/Controllers/Import/ConfigurationController.php b/app/Http/Controllers/Import/ConfigurationController.php
deleted file mode 100644
index 7f6ee65b1c..0000000000
--- a/app/Http/Controllers/Import/ConfigurationController.php
+++ /dev/null
@@ -1,147 +0,0 @@
-.
- */
-declare(strict_types=1);
-
-namespace FireflyIII\Http\Controllers\Import;
-
-use FireflyIII\Exceptions\FireflyException;
-use FireflyIII\Http\Controllers\Controller;
-use FireflyIII\Http\Middleware\IsDemoUser;
-use FireflyIII\Import\Configuration\ConfiguratorInterface;
-use FireflyIII\Models\ImportJob;
-use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
-use Illuminate\Http\Request;
-use Log;
-
-/**
- * Class ConfigurationController
- */
-class ConfigurationController extends Controller
-{
- /** @var ImportJobRepositoryInterface */
- public $repository;
-
- /**
- *
- */
- public function __construct()
- {
- parent::__construct();
-
- $this->middleware(
- function ($request, $next) {
- app('view')->share('mainTitleIcon', 'fa-archive');
- app('view')->share('title', trans('firefly.import_index_title'));
- $this->repository = app(ImportJobRepositoryInterface::class);
-
- return $next($request);
- }
- );
- $this->middleware(IsDemoUser::class);
- }
-
- /**
- * Configure the job. This method is returned to until job is deemed "configured".
- *
- * @param ImportJob $job
- *
- * @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector|\Illuminate\View\View
- *
- * @throws FireflyException
- */
- public function index(ImportJob $job)
- {
- // create configuration class:
- $configurator = $this->makeConfigurator($job);
-
- // is the job already configured?
- if ($configurator->isJobConfigured()) {
- $this->repository->updateStatus($job, 'configured');
-
- return redirect(route('import.status', [$job->key]));
- }
-
- $this->repository->updateStatus($job, 'configuring');
-
- $view = $configurator->getNextView();
- $data = $configurator->getNextData();
- $subTitle = trans('firefly.import_config_bread_crumb');
- $subTitleIcon = 'fa-wrench';
-
- return view($view, compact('data', 'job', 'subTitle', 'subTitleIcon'));
- }
-
- /**
- * Store the configuration. Returns to "configure" method until job is configured.
- *
- * @param Request $request
- * @param ImportJob $job
- *
- * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
- *
- * @throws FireflyException
- */
- public function post(Request $request, ImportJob $job)
- {
- Log::debug('Now in postConfigure()', ['job' => $job->key]);
- $configurator = $this->makeConfigurator($job);
-
- // is the job already configured?
- if ($configurator->isJobConfigured()) {
- return redirect(route('import.status', [$job->key]));
- }
- $data = $request->all();
- $configurator->configureJob($data);
-
- // get possible warning from configurator:
- $warning = $configurator->getWarningMessage();
-
- if (\strlen($warning) > 0) {
- $request->session()->flash('warning', $warning);
- }
-
- // return to configure
- return redirect(route('import.configure', [$job->key]));
- }
-
- /**
- * @param ImportJob $job
- *
- * @return ConfiguratorInterface
- *
- * @throws FireflyException
- */
- private function makeConfigurator(ImportJob $job): ConfiguratorInterface
- {
- $type = $job->file_type;
- $key = sprintf('import.configuration.%s', $type);
- $className = config($key);
- if (null === $className || !class_exists($className)) {
- throw new FireflyException(sprintf('Cannot find configurator class for job of type "%s".', $type)); // @codeCoverageIgnore
- }
- Log::debug(sprintf('Going to create class "%s"', $className));
- /** @var ConfiguratorInterface $configurator */
- $configurator = app($className);
- $configurator->setJob($job);
-
- return $configurator;
- }
-}
diff --git a/app/Http/Controllers/Import/IndexController.php b/app/Http/Controllers/Import/IndexController.php
index c340ef8f1e..a6fe9d3167 100644
--- a/app/Http/Controllers/Import/IndexController.php
+++ b/app/Http/Controllers/Import/IndexController.php
@@ -24,17 +24,14 @@ namespace FireflyIII\Http\Controllers\Import;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Http\Controllers\Controller;
-use FireflyIII\Http\Middleware\IsDemoUser;
-use FireflyIII\Import\Routine\RoutineInterface;
+use FireflyIII\Import\Prerequisites\PrerequisitesInterface;
use FireflyIII\Models\ImportJob;
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
-use Illuminate\Http\Request;
+use FireflyIII\Repositories\User\UserRepositoryInterface;
use Illuminate\Http\Response as LaravelResponse;
use Log;
-use Preferences;
use View;
-
/**
* Class FileController.
*/
@@ -43,6 +40,9 @@ class IndexController extends Controller
/** @var ImportJobRepositoryInterface */
public $repository;
+ /** @var UserRepositoryInterface */
+ public $userRepository;
+
/**
*
*/
@@ -54,33 +54,96 @@ class IndexController extends Controller
function ($request, $next) {
app('view')->share('mainTitleIcon', 'fa-archive');
app('view')->share('title', trans('firefly.import_index_title'));
- $this->repository = app(ImportJobRepositoryInterface::class);
+ $this->repository = app(ImportJobRepositoryInterface::class);
+ $this->userRepository = app(UserRepositoryInterface::class);
return $next($request);
}
);
- $this->middleware(IsDemoUser::class)->except(['index']);
}
/**
- * Creates a new import job for $bank with the default (global) job configuration.
+ * Creates a new import job for $importProvider.
*
- * @param string $bank
+ * @param string $importProvider
*
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*
* @throws FireflyException
*/
- public function create(string $bank)
+ public function create(string $importProvider)
{
- if (true === !config(sprintf('import.enabled.%s', $bank))) {
- throw new FireflyException(sprintf('Cannot import from "%s" at this time.', $bank)); // @codeCoverageIgnore
+ Log::debug(sprintf('Will create job for provider "%s"', $importProvider));
+ // can only create "fake" for demo user.
+ $providers = array_keys($this->getProviders());
+ if (!\in_array($importProvider, $providers, true)) {
+ Log::error(sprintf('%s-provider is disabled. Cannot create job.', $importProvider));
+ session()->flash('warning', trans('import.cannot_create_for_provider', ['provider' => $importProvider]));
+
+ return redirect(route('import.index'));
}
- $importJob = $this->repository->create($bank);
+ $importJob = $this->repository->create($importProvider);
+ Log::debug(sprintf('Created job #%d for provider %s', $importJob->id, $importProvider));
+
+ $hasPreReq = (bool)config(sprintf('import.has_prereq.%s', $importProvider));
+ $hasConfig = (bool)config(sprintf('import.has_job_config.%s', $importProvider));
+ // if job provider has no prerequisites:
+ if ($hasPreReq === false) {
+ Log::debug('Provider has no prerequisites. Continue.');
+ // if job provider also has no configuration:
+ if ($hasConfig === false) {
+ // @codeCoverageIgnoreStart
+ Log::debug('Provider needs no configuration for job. Job is ready to start.');
+ $this->repository->updateStatus($importJob, 'ready_to_run');
+ Log::debug('Redirect to status-page.');
+
+ return redirect(route('import.job.status.index', [$importJob->key]));
+ // @codeCoverageIgnoreEnd
+ }
+
+ // update job to say "has_prereq".
+ $this->repository->setStatus($importJob, 'has_prereq');
+
+ // redirect to job configuration.
+ Log::debug('Redirect to configuration.');
+
+ return redirect(route('import.job.configuration.index', [$importJob->key]));
+ }
+ Log::debug('Job provider has prerequisites.');
+ // if need to set prerequisites, do that first.
+ $class = (string)config(sprintf('import.prerequisites.%s', $importProvider));
+ if (!class_exists($class)) {
+ throw new FireflyException(sprintf('No class to handle prerequisites for "%s".', $importProvider)); // @codeCoverageIgnore
+ }
+ /** @var PrerequisitesInterface $providerPre */
+ $providerPre = app($class);
+ $providerPre->setUser(auth()->user());
+
+ if (!$providerPre->isComplete()) {
+ Log::debug('Job provider prerequisites are not yet filled in. Redirect to prerequisites-page.');
+
+ // redirect to global prerequisites
+ return redirect(route('import.prerequisites.index', [$importProvider, $importJob->key]));
+ }
+ Log::debug('Prerequisites are complete.');
+
+ // update job to say "has_prereq".
+ $this->repository->setStatus($importJob, 'has_prereq');
+ if ($hasConfig === false) {
+ // @codeCoverageIgnoreStart
+ Log::debug('Provider has no configuration. Job is ready to start.');
+ $this->repository->updateStatus($importJob, 'ready_to_run');
+ Log::debug('Redirect to status-page.');
+
+ return redirect(route('import.job.status.index', [$importJob->key]));
+ // @codeCoverageIgnoreEnd
+ }
+ Log::debug('Job has configuration. Redirect to job-config.');
+
+ // Otherwise just redirect to job configuration.
+ return redirect(route('import.job.configuration.index', [$importJob->key]));
- // from here, always go to configure step.
- return redirect(route('import.configure', [$importJob->key]));
}
/**
@@ -90,22 +153,18 @@ class IndexController extends Controller
*
* @return LaravelResponse
*/
- public function download(ImportJob $job)
+ public function download(ImportJob $job): LaravelResponse
{
Log::debug('Now in download()', ['job' => $job->key]);
- $config = $job->configuration;
-
+ $config = $this->repository->getConfiguration($job);
// This is CSV import specific:
- $config['column-roles-complete'] = false;
- $config['column-mapping-complete'] = false;
- $config['initial-config-complete'] = false;
- $config['has-file-upload'] = false;
- $config['delimiter'] = "\t" === $config['delimiter'] ? 'tab' : $config['delimiter'];
- unset($config['stage']);
-
- $result = json_encode($config, JSON_PRETTY_PRINT);
- $name = sprintf('"%s"', addcslashes('import-configuration-' . date('Y-m-d') . '.json', '"\\'));
+ $config['delimiter'] = $config['delimiter'] ?? ',';
+ $config['delimiter'] = "\t" === $config['delimiter'] ? 'tab' : $config['delimiter'];
+ // this prevents private information from escaping
+ $config['column-mapping-config'] = [];
+ $result = json_encode($config, JSON_PRETTY_PRINT);
+ $name = sprintf('"%s"', addcslashes('import-configuration-' . date('Y-m-d') . '.json', '"\\'));
/** @var LaravelResponse $response */
$response = response($result, 200);
$response->header('Content-disposition', 'attachment; filename=' . $name)
@@ -127,78 +186,60 @@ class IndexController extends Controller
*/
public function index()
{
- $subTitle = trans('firefly.import_index_sub_title');
+ $providers = $this->getProviders();
+ $subTitle = trans('import.index_breadcrumb');
$subTitleIcon = 'fa-home';
- $routines = config('import.enabled');
- return view('import.index', compact('subTitle', 'subTitleIcon', 'routines'));
+ return view('import.index', compact('subTitle', 'subTitleIcon', 'providers'));
}
/**
- * @param Request $request
- * @param string $bank
- *
- * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
+ * @return array
*/
- public function reset(Request $request, string $bank)
+ private function getProviders(): array
{
- if ($bank === 'bunq') {
- // remove bunq related preferences.
- Preferences::delete('bunq_api_key');
- Preferences::delete('bunq_server_public_key');
- Preferences::delete('bunq_private_key');
- Preferences::delete('bunq_public_key');
- Preferences::delete('bunq_installation_token');
- Preferences::delete('bunq_installation_id');
- Preferences::delete('bunq_device_server_id');
- Preferences::delete('external_ip');
+ // get and filter all import routines:
+ /** @var array $config */
+ $providerNames = array_keys(config('import.enabled'));
+ $providers = [];
+ $isDemoUser = $this->userRepository->hasRole(auth()->user(), 'demo');
+ $isDebug = (bool)config('app.debug');
+ foreach ($providerNames as $providerName) {
+ //Log::debug(sprintf('Now with provider %s', $providerName));
+ // only consider enabled providers
+ $enabled = (bool)config(sprintf('import.enabled.%s', $providerName));
+ $allowedForDemo = (bool)config(sprintf('import.allowed_for_demo.%s', $providerName));
+ $allowedForUser = (bool)config(sprintf('import.allowed_for_user.%s', $providerName));
+ if ($enabled === false) {
+ //Log::debug('Provider is not enabled. NEXT!');
+ continue;
+ }
+ if ($isDemoUser === true && $allowedForDemo === false) {
+ //Log::debug('User is demo and this provider is not allowed for demo user. NEXT!');
+ continue;
+ }
+ if ($isDemoUser === false && $allowedForUser === false && $isDebug === false) {
+ //Log::debug('User is not demo and this provider is not allowed for such users. NEXT!');
+ continue; // @codeCoverageIgnore
+ }
+
+ $providers[$providerName] = [
+ 'has_prereq' => (bool)config('import.has_prereq.' . $providerName),
+ ];
+ $class = (string)config(sprintf('import.prerequisites.%s', $providerName));
+ $result = false;
+ if ($class !== '' && class_exists($class)) {
+ //Log::debug('Will not check prerequisites.');
+ /** @var PrerequisitesInterface $object */
+ $object = app($class);
+ $object->setUser(auth()->user());
+ $result = $object->isComplete();
+ }
+ $providers[$providerName]['prereq_complete'] = $result;
}
+ Log::debug(sprintf('Enabled providers: %s', json_encode(array_keys($providers))));
- if ($bank === 'spectre') {
- // remove spectre related preferences:
- Preferences::delete('spectre_client_id');
- Preferences::delete('spectre_app_secret');
- Preferences::delete('spectre_service_secret');
- Preferences::delete('spectre_app_id');
- Preferences::delete('spectre_secret');
- Preferences::delete('spectre_private_key');
- Preferences::delete('spectre_public_key');
- Preferences::delete('spectre_customer');
- }
-
- Preferences::mark();
- $request->session()->flash('info', (string)trans('firefly.settings_reset_for_' . $bank));
-
- return redirect(route('import.index'));
-
- }
-
- /**
- * @param ImportJob $job
- *
- * @return \Illuminate\Http\JsonResponse
- *
- * @throws FireflyException
- */
- public function start(ImportJob $job)
- {
- $type = $job->file_type;
- $key = sprintf('import.routine.%s', $type);
- $className = config($key);
- if (null === $className || !class_exists($className)) {
- throw new FireflyException(sprintf('Cannot find import routine class for job of type "%s".', $type)); // @codeCoverageIgnore
- }
-
- /** @var RoutineInterface $routine */
- $routine = app($className);
- $routine->setJob($job);
- $result = $routine->run();
-
- if ($result) {
- return response()->json(['run' => 'ok']);
- }
-
- throw new FireflyException('Job did not complete successfully. Please review the log files.');
+ return $providers;
}
}
diff --git a/app/Http/Controllers/Import/JobConfigurationController.php b/app/Http/Controllers/Import/JobConfigurationController.php
new file mode 100644
index 0000000000..fc11df8284
--- /dev/null
+++ b/app/Http/Controllers/Import/JobConfigurationController.php
@@ -0,0 +1,184 @@
+.
+ */
+declare(strict_types=1);
+
+namespace FireflyIII\Http\Controllers\Import;
+
+use FireflyIII\Exceptions\FireflyException;
+use FireflyIII\Http\Controllers\Controller;
+use FireflyIII\Import\JobConfiguration\JobConfigurationInterface;
+use FireflyIII\Models\ImportJob;
+use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
+use Illuminate\Http\Request;
+use Illuminate\Http\UploadedFile;
+use Illuminate\Support\MessageBag;
+use Log;
+
+/**
+ * Class JobConfigurationController
+ */
+class JobConfigurationController extends Controller
+{
+ /** @var ImportJobRepositoryInterface */
+ public $repository;
+
+ /**
+ *
+ */
+ public function __construct()
+ {
+ parent::__construct();
+
+ $this->middleware(
+ function ($request, $next) {
+ app('view')->share('mainTitleIcon', 'fa-archive');
+ app('view')->share('title', trans('firefly.import_index_title'));
+ $this->repository = app(ImportJobRepositoryInterface::class);
+
+ return $next($request);
+ }
+ );
+ }
+
+ /**
+ * Configure the job. This method is returned to until job is deemed "configured".
+ *
+ * @param ImportJob $importJob
+ *
+ * @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector|\Illuminate\View\View
+ *
+ * @throws FireflyException
+ */
+ public function index(ImportJob $importJob)
+ {
+ Log::debug('Now in JobConfigurationController::index()');
+ // catch impossible status:
+ $allowed = ['has_prereq', 'need_job_config'];
+ if (null !== $importJob && !\in_array($importJob->status, $allowed, true)) {
+ Log::debug(sprintf('Job has state "%s", but we only accept %s', $importJob->status, json_encode($allowed)));
+ session()->flash('error', trans('import.bad_job_status', ['status' => $importJob->status]));
+
+ return redirect(route('import.index'));
+ }
+ Log::debug(sprintf('Now in JobConfigurationController::index() with job "%s" and status "%s"', $importJob->key, $importJob->status));
+
+ // if provider has no config, just push it through:
+ $importProvider = $importJob->provider;
+ if (!(bool)config(sprintf('import.has_job_config.%s', $importProvider))) {
+ // @codeCoverageIgnoreStart
+ Log::debug('Job needs no config, is ready to run!');
+ $this->repository->updateStatus($importJob, 'ready_to_run');
+
+ return redirect(route('import.job.status.index', [$importJob->key]));
+ // @codeCoverageIgnoreEnd
+ }
+
+ // create configuration class:
+ $configurator = $this->makeConfigurator($importJob);
+
+ // is the job already configured?
+ if ($configurator->configurationComplete()) {
+ Log::debug('Config is complete, set status to ready_to_run.');
+ $this->repository->updateStatus($importJob, 'ready_to_run');
+
+ return redirect(route('import.job.status.index', [$importJob->key]));
+ }
+
+ $view = $configurator->getNextView();
+ $data = $configurator->getNextData();
+ $subTitle = trans('import.job_configuration_breadcrumb', ['key' => $importJob->key]);
+ $subTitleIcon = 'fa-wrench';
+
+ return view($view, compact('data', 'importJob', 'subTitle', 'subTitleIcon'));
+ }
+
+ /**
+ * Store the configuration. Returns to "configure" method until job is configured.
+ *
+ * @param Request $request
+ * @param ImportJob $importJob
+ *
+ * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
+ *
+ * @throws FireflyException
+ */
+ public function post(Request $request, ImportJob $importJob)
+ {
+ // catch impossible status:
+ $allowed = ['has_prereq', 'need_job_config'];
+ if (null !== $importJob && !\in_array($importJob->status, $allowed, true)) {
+ session()->flash('error', trans('import.bad_job_status', ['status' => $importJob->status]));
+
+ return redirect(route('import.index'));
+ }
+
+ Log::debug('Now in postConfigure()', ['job' => $importJob->key]);
+ $configurator = $this->makeConfigurator($importJob);
+
+ // is the job already configured?
+ if ($configurator->configurationComplete()) {
+ $this->repository->updateStatus($importJob, 'ready_to_run');
+
+ return redirect(route('import.job.status.index', [$importJob->key]));
+ }
+
+ // uploaded files are attached to the job.
+ // the configurator can then handle them.
+ $result = new MessageBag;
+
+ /** @var UploadedFile $upload */
+ foreach ($request->allFiles() as $name => $upload) {
+ $result = $this->repository->storeFileUpload($importJob, $name, $upload);
+ }
+ $data = $request->all();
+ $messages = $configurator->configureJob($data);
+ $result->merge($messages);
+
+ if ($messages->count() > 0) {
+ $request->session()->flash('warning', $messages->first());
+ }
+
+ // return to configure
+ return redirect(route('import.job.configuration.index', [$importJob->key]));
+ }
+
+ /**
+ * @param ImportJob $importJob
+ *
+ * @return JobConfigurationInterface
+ *
+ * @throws FireflyException
+ */
+ private function makeConfigurator(ImportJob $importJob): JobConfigurationInterface
+ {
+ $key = sprintf('import.configuration.%s', $importJob->provider);
+ $className = (string)config($key);
+ if (null === $className || !class_exists($className)) {
+ throw new FireflyException(sprintf('Cannot find configurator class for job with provider "%s".', $importJob->provider)); // @codeCoverageIgnore
+ }
+ Log::debug(sprintf('Going to create class "%s"', $className));
+ /** @var JobConfigurationInterface $configurator */
+ $configurator = app($className);
+ $configurator->setImportJob($importJob);
+
+ return $configurator;
+ }
+}
diff --git a/app/Http/Controllers/Import/JobStatusController.php b/app/Http/Controllers/Import/JobStatusController.php
new file mode 100644
index 0000000000..d512e82196
--- /dev/null
+++ b/app/Http/Controllers/Import/JobStatusController.php
@@ -0,0 +1,232 @@
+.
+ */
+declare(strict_types=1);
+
+namespace FireflyIII\Http\Controllers\Import;
+
+use Exception;
+use FireflyIII\Exceptions\FireflyException;
+use FireflyIII\Http\Controllers\Controller;
+use FireflyIII\Import\Routine\RoutineInterface;
+use FireflyIII\Import\Storage\ImportArrayStorage;
+use FireflyIII\Models\ImportJob;
+use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
+use Illuminate\Http\JsonResponse;
+use Log;
+
+/**
+ * Class JobStatusController
+ */
+class JobStatusController extends Controller
+{
+ /** @var ImportJobRepositoryInterface */
+ private $repository;
+
+ /**
+ *
+ */
+ public function __construct()
+ {
+ parent::__construct();
+
+ $this->middleware(
+ function ($request, $next) {
+ app('view')->share('mainTitleIcon', 'fa-archive');
+ app('view')->share('title', trans('firefly.import_index_title'));
+ $this->repository = app(ImportJobRepositoryInterface::class);
+
+ return $next($request);
+ }
+ );
+ }
+
+ /**
+ * @param ImportJob $importJob
+ *
+ * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
+ */
+ public function index(ImportJob $importJob)
+ {
+ $subTitleIcon = 'fa-gear';
+ $subTitle = trans('import.job_status_breadcrumb', ['key' => $importJob->key]);
+
+ return view('import.status', compact('importJob', 'subTitle', 'subTitleIcon'));
+ }
+
+ /**
+ * @param ImportJob $importJob
+ *
+ * @return JsonResponse
+ */
+ public function json(ImportJob $importJob): JsonResponse
+ {
+ $count = \count($importJob->transactions);
+ $json = [
+ 'status' => $importJob->status,
+ 'errors' => $importJob->errors,
+ 'count' => $count,
+ 'tag_id' => $importJob->tag_id,
+ 'tag_name' => null === $importJob->tag_id ? null : $importJob->tag->tag,
+ 'report_txt' => trans('import.unknown_import_result'),
+ 'download_config' => false,
+ 'download_config_text' => '',
+ ];
+
+ if ($importJob->provider === 'file') {
+ $json['download_config'] = true;
+ $json['download_config_text']
+ = trans('import.should_download_config', ['route' => route('import.job.download', [$importJob->key])]) . ' '
+ . trans('import.share_config_file');
+ }
+
+ // if count is zero:
+ if (null !== $importJob->tag_id) {
+ $count = $importJob->tag->transactionJournals->count();
+ }
+ if ($count === 0) {
+ $json['report_txt'] = trans('import.result_no_transactions');
+ }
+ if ($count === 1 && null !== $importJob->tag_id) {
+ $json['report_txt'] = trans(
+ 'import.result_one_transaction', ['route' => route('tags.show', [$importJob->tag_id, 'all']), 'tag' => $importJob->tag->tag]
+ );
+ }
+ if ($count > 1 && null !== $importJob->tag_id) {
+ $json['report_txt'] = trans(
+ 'import.result_many_transactions',
+ ['count' => $count, 'route' => route('tags.show', [$importJob->tag_id, 'all']), 'tag' => $importJob->tag->tag]
+ );
+ }
+
+ return response()->json($json);
+ }
+
+ /**
+ * @param ImportJob $importJob
+ *
+ * @return JsonResponse
+ */
+ public function start(ImportJob $importJob): JsonResponse
+ {
+ // catch impossible status:
+ $allowed = ['ready_to_run', 'need_job_config', 'error']; // todo remove error
+
+ if (null !== $importJob && !\in_array($importJob->status, $allowed, true)) {
+ Log::error('Job is not ready.');
+ $this->repository->setStatus($importJob, 'error');
+
+ return response()->json(
+ ['status' => 'NOK', 'message' => sprintf('JobStatusController::start expects status "ready_to_run" instead of "%s".', $importJob->status)]
+ );
+ }
+ $importProvider = $importJob->provider;
+ $key = sprintf('import.routine.%s', $importProvider);
+ $className = config($key);
+ if (null === $className || !class_exists($className)) {
+ // @codeCoverageIgnoreStart
+ return response()->json(
+ ['status' => 'NOK', 'message' => sprintf('Cannot find import routine class for job of type "%s".', $importProvider)]
+ );
+ // @codeCoverageIgnoreEnd
+ }
+
+ /** @var RoutineInterface $routine */
+ $routine = app($className);
+ $routine->setImportJob($importJob);
+ try {
+ $routine->run();
+ } catch (FireflyException|Exception $e) {
+ $message = 'The import routine crashed: ' . $e->getMessage();
+ Log::error($message);
+ Log::error($e->getTraceAsString());
+
+ // set job errored out:
+ $this->repository->setStatus($importJob, 'error');
+
+ return response()->json(['status' => 'NOK', 'message' => $message]);
+ }
+
+ // expect nothing from routine, just return OK to user.
+ return response()->json(['status' => 'OK', 'message' => 'stage_finished']);
+ }
+
+ /**
+ * Store does three things:
+ *
+ * - Store the transactions.
+ * - Add them to a tag.
+ *
+ * @param ImportJob $importJob
+ *
+ * @return JsonResponse
+ */
+ public function store(ImportJob $importJob): JsonResponse
+ {
+ // catch impossible status:
+ $allowed = ['provider_finished', 'storing_data'];
+ if (null !== $importJob && !\in_array($importJob->status, $allowed, true)) {
+ Log::error('Job is not ready.');
+
+ return response()->json(
+ ['status' => 'NOK', 'message' => sprintf('JobStatusController::start expects status "provider_finished" instead of "%s".', $importJob->status)]
+ );
+ }
+
+ // set job to be storing data:
+ $this->repository->setStatus($importJob, 'storing_data');
+
+ try {
+ $this->storeTransactions($importJob);
+ } catch (FireflyException $e) {
+ $message = 'The import storage routine crashed: ' . $e->getMessage();
+ Log::error($message);
+ Log::error($e->getTraceAsString());
+
+ // set job errored out:
+ $this->repository->setStatus($importJob, 'error');
+
+ return response()->json(['status' => 'NOK', 'message' => $message]);
+ }
+ // set storage to be finished:
+ $this->repository->setStatus($importJob, 'storage_finished');
+
+
+ // expect nothing from routine, just return OK to user.
+ return response()->json(['status' => 'OK', 'message' => 'storage_finished']);
+ }
+
+ /**
+ * @param ImportJob $importJob
+ *
+ * @throws FireflyException
+ */
+ private function storeTransactions(ImportJob $importJob): void
+ {
+ /** @var ImportArrayStorage $storage */
+ $storage = app(ImportArrayStorage::class);
+ $storage->setImportJob($importJob);
+ try {
+ $storage->store();
+ } catch (FireflyException|Exception $e) {
+ throw new FireflyException($e->getMessage());
+ }
+ }
+}
diff --git a/app/Http/Controllers/Import/PrerequisitesController.php b/app/Http/Controllers/Import/PrerequisitesController.php
index 76b4973321..d0e4d5bbd6 100644
--- a/app/Http/Controllers/Import/PrerequisitesController.php
+++ b/app/Http/Controllers/Import/PrerequisitesController.php
@@ -24,8 +24,9 @@ namespace FireflyIII\Http\Controllers\Import;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Http\Controllers\Controller;
-use FireflyIII\Http\Middleware\IsDemoUser;
use FireflyIII\Import\Prerequisites\PrerequisitesInterface;
+use FireflyIII\Models\ImportJob;
+use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
use Illuminate\Http\Request;
use Log;
@@ -35,6 +36,9 @@ use Log;
class PrerequisitesController extends Controller
{
+ /** @var ImportJobRepositoryInterface */
+ private $repository;
+
/**
*
*/
@@ -46,48 +50,59 @@ class PrerequisitesController extends Controller
function ($request, $next) {
app('view')->share('mainTitleIcon', 'fa-archive');
app('view')->share('title', trans('firefly.import_index_title'));
+ app('view')->share('subTitleIcon', 'fa-check');
+
+ $this->repository = app(ImportJobRepositoryInterface::class);
return $next($request);
}
);
- $this->middleware(IsDemoUser::class);
}
/**
- * Once there are no prerequisites, this method will create an importjob object and
- * redirect the user to a view where this object can be used by a bank specific
- * class to process.
+ * This method will process and store import provider global prerequisites
+ * such as API keys.
*
- * @param string $bank
- *
- * @return \Illuminate\View\View|\Illuminate\Contracts\View\Factory|\Illuminate\Http\RedirectResponse
+ * @param string $importProvider
+ * @param ImportJob $importJob
*
+ * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
* @throws FireflyException
*/
- public function index(string $bank)
+ public function index(string $importProvider, ImportJob $importJob = null)
{
- if (true === !config(sprintf('import.enabled.%s', $bank))) {
- throw new FireflyException(sprintf('Cannot import from "%s" at this time.', $bank)); // @codeCoverageIgnore
- }
- $class = (string)config(sprintf('import.prerequisites.%s', $bank));
- if (!class_exists($class)) {
- throw new FireflyException(sprintf('No class to handle "%s".', $bank)); // @codeCoverageIgnore
+ // catch impossible status:
+ $allowed = ['new'];
+ if (null !== $importJob && !in_array($importJob->status, $allowed)) {
+ Log::error(sprintf('Job has state "%s" but this Prerequisites::index() only accepts %s', $importJob->status, json_encode($allowed)));
+ session()->flash('error', trans('import.bad_job_status', ['status' => $importJob->status]));
+
+ return redirect(route('import.index'));
}
+ app('view')->share('subTitle', trans('import.prerequisites_breadcrumb_' . $importProvider));
+ $class = (string)config(sprintf('import.prerequisites.%s', $importProvider));
+ if (!class_exists($class)) {
+ throw new FireflyException(sprintf('No class to handle prerequisites for "%s".', $importProvider)); // @codeCoverageIgnore
+ }
/** @var PrerequisitesInterface $object */
$object = app($class);
$object->setUser(auth()->user());
- if ($object->hasPrerequisites()) {
- $view = $object->getView();
- $parameters = ['title' => (string)trans('firefly.import_index_title'), 'mainTitleIcon' => 'fa-archive'];
- $parameters = array_merge($object->getViewParameters(), $parameters);
+ if (null !== $importJob && $object->isComplete()) {
+ // update job:
+ $this->repository->setStatus($importJob, 'has_prereq');
- return view($view, $parameters);
+ // redirect to job config:
+ return redirect(route('import.job.configuration.index', [$importJob->key]));
}
- // if no (more) prerequisites, return to create a job:
- return redirect(route('import.create-job', [$bank]));
+
+ $view = $object->getView();
+ $parameters = ['title' => (string)trans('firefly.import_index_title'), 'mainTitleIcon' => 'fa-archive', 'importJob' => $importJob];
+ $parameters = array_merge($object->getViewParameters(), $parameters);
+
+ return view($view, $parameters);
}
/**
@@ -98,42 +113,63 @@ class PrerequisitesController extends Controller
*
* @see PrerequisitesInterface::storePrerequisites
*
- * @param Request $request
- * @param string $bank
+ * @param Request $request
+ * @param string $importProvider
+ * @param ImportJob $importJob
*
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*
* @throws FireflyException
*/
- public function post(Request $request, string $bank)
+ public function post(Request $request, string $importProvider, ImportJob $importJob = null)
{
- Log::debug(sprintf('Now in postPrerequisites for %s', $bank));
+ Log::debug(sprintf('Now in postPrerequisites for %s', $importProvider));
- if (true === !config(sprintf('import.enabled.%s', $bank))) {
- throw new FireflyException(sprintf('Cannot import from "%s" at this time.', $bank)); // @codeCoverageIgnore
+ // catch impossible status:
+ $allowed = ['new'];
+ if (null !== $importJob && !\in_array($importJob->status, $allowed, true)) {
+ Log::error(sprintf('Job has state "%s" but this Prerequisites::post() only accepts %s', $importJob->status, json_encode($allowed)));
+ session()->flash('error', trans('import.bad_job_status', ['status' => $importJob->status]));
+
+ return redirect(route('import.index'));
}
- $class = (string)config(sprintf('import.prerequisites.%s', $bank));
+
+ $class = (string)config(sprintf('import.prerequisites.%s', $importProvider));
if (!class_exists($class)) {
throw new FireflyException(sprintf('Cannot find class %s', $class)); // @codeCoverageIgnore
}
/** @var PrerequisitesInterface $object */
$object = app($class);
$object->setUser(auth()->user());
- if (!$object->hasPrerequisites()) {
- Log::debug(sprintf('No more prerequisites for %s, move to form.', $bank));
-
- return redirect(route('import.create-job', [$bank]));
- }
Log::debug('Going to store entered prerequisites.');
// store post data
- $result = $object->storePrerequisites($request);
+ $data = $request->all();
+ $result = $object->storePrerequisites($data);
Log::debug(sprintf('Result of storePrerequisites has message count: %d', $result->count()));
if ($result->count() > 0) {
$request->session()->flash('error', $result->first());
+
+ // redirect back to job, if has job:
+ return redirect(route('import.prerequisites.index', [$importProvider, $importJob->key ?? '']))->withInput();
}
- return redirect(route('import.prerequisites', [$bank]));
+ // session flash!
+ $request->session()->flash('success', (string)trans('import.prerequisites_saved_for_' . $importProvider));
+
+ // if has job, redirect to global config for provider
+ // if no job, back to index!
+ if (null === $importJob) {
+ return redirect(route('import.index'));
+ }
+
+ // update job:
+ $this->repository->setStatus($importJob, 'has_prereq');
+
+ // redirect to job config:
+ return redirect(route('import.job.configuration.index', [$importJob->key]));
+
+
}
}
diff --git a/app/Http/Controllers/Import/StatusController.php b/app/Http/Controllers/Import/StatusController.php
deleted file mode 100644
index 4c95ec77a3..0000000000
--- a/app/Http/Controllers/Import/StatusController.php
+++ /dev/null
@@ -1,125 +0,0 @@
-.
- */
-declare(strict_types=1);
-
-namespace FireflyIII\Http\Controllers\Import;
-
-use FireflyIII\Http\Controllers\Controller;
-use FireflyIII\Http\Middleware\IsDemoUser;
-use FireflyIII\Models\ImportJob;
-use FireflyIII\Repositories\Tag\TagRepositoryInterface;
-use Log;
-
-/**
- * Class StatusController
- */
-class StatusController extends Controller
-{
- /**
- *
- */
- public function __construct()
- {
- parent::__construct();
-
- $this->middleware(
- function ($request, $next) {
- app('view')->share('mainTitleIcon', 'fa-archive');
- app('view')->share('title', trans('firefly.import_index_title'));
-
- return $next($request);
- }
- );
- $this->middleware(IsDemoUser::class);
- }
-
- /**
- * @param ImportJob $job
- *
- * @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector|\Illuminate\View\View
- */
- public function index(ImportJob $job)
- {
- $statuses = ['configured', 'running', 'finished', 'error'];
- if (!\in_array($job->status, $statuses)) {
- return redirect(route('import.configure', [$job->key]));
- }
- $subTitle = trans('import.status_sub_title');
- $subTitleIcon = 'fa-star';
-
- return view('import.status', compact('job', 'subTitle', 'subTitleIcon'));
- }
-
- /**
- * Show status of import job in JSON.
- *
- * @param ImportJob $job
- *
- * @return \Illuminate\Http\JsonResponse
- */
- public function json(ImportJob $job)
- {
- $result = [
- 'started' => false,
- 'finished' => false,
- 'running' => false,
- 'errors' => array_values($job->extended_status['errors']),
- 'percentage' => 0,
- 'show_percentage' => false,
- 'steps' => $job->extended_status['steps'],
- 'done' => $job->extended_status['done'],
- 'statusText' => trans('import.status_job_' . $job->status),
- 'status' => $job->status,
- 'finishedText' => '',
- ];
-
- if (0 !== $job->extended_status['steps']) {
- $result['percentage'] = round(($job->extended_status['done'] / $job->extended_status['steps']) * 100, 0);
- $result['show_percentage'] = true;
- }
- if ('finished' === $job->status) {
- $result['finished'] = true;
- $tagId = (int)$job->extended_status['tag'];
- if ($tagId !== 0) {
- /** @var TagRepositoryInterface $repository */
- $repository = app(TagRepositoryInterface::class);
- $tag = $repository->find($tagId);
- $count = $tag->transactionJournals()->count();
- $result['finishedText'] = trans(
- 'import.status_finished_job', ['count' => $count, 'link' => route('tags.show', [$tag->id, 'all']), 'tag' => $tag->tag]
- );
- }
-
- if ($tagId === 0) {
- $result['finishedText'] = trans('import.status_finished_no_tag'); // @codeCoverageIgnore
- }
- }
-
- if ('running' === $job->status) {
- $result['started'] = true;
- $result['running'] = true;
- }
- $result['percentage'] = $result['percentage'] > 100 ? 100 : $result['percentage'];
- Log::debug(sprintf('JOB STATUS: %d/%d', $result['done'], $result['steps']));
-
- return response()->json($result);
- }
-}
diff --git a/app/Http/Controllers/JavascriptController.php b/app/Http/Controllers/JavascriptController.php
index d47992d9ed..0ebb2d5192 100644
--- a/app/Http/Controllers/JavascriptController.php
+++ b/app/Http/Controllers/JavascriptController.php
@@ -29,6 +29,7 @@ use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use Illuminate\Http\Request;
+use Illuminate\Http\Response;
use Log;
use Preferences;
@@ -68,9 +69,9 @@ class JavascriptController extends Controller
/**
* @param CurrencyRepositoryInterface $repository
*
- * @return \Illuminate\Http\Response
+ * @return Response
*/
- public function currencies(CurrencyRepositoryInterface $repository)
+ public function currencies(CurrencyRepositoryInterface $repository): Response
{
$currencies = $repository->get();
$data = ['currencies' => []];
@@ -102,7 +103,8 @@ class JavascriptController extends Controller
}
/** @var TransactionCurrency $currency */
$currency = $currencyRepository->findNull($currencyId);
- if (0 === $currencyId) {
+ if (null === $currency) {
+ /** @var TransactionCurrency $currency */
$currency = app('amount')->getDefaultCurrency();
}
diff --git a/app/Http/Controllers/Json/AutoCompleteController.php b/app/Http/Controllers/Json/AutoCompleteController.php
index b01069520e..6ff6c92e1d 100644
--- a/app/Http/Controllers/Json/AutoCompleteController.php
+++ b/app/Http/Controllers/Json/AutoCompleteController.php
@@ -35,6 +35,7 @@ use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
use FireflyIII\Support\CacheProperties;
+use Illuminate\Http\JsonResponse;
/**
* Class AutoCompleteController.
@@ -47,7 +48,7 @@ class AutoCompleteController extends Controller
*
* @param AccountRepositoryInterface $repository
*
- * @return \Illuminate\Http\JsonResponse
+ * @return JsonResponse
*/
public function allAccounts(AccountRepositoryInterface $repository)
{
@@ -64,9 +65,9 @@ class AutoCompleteController extends Controller
/**
* @param JournalCollectorInterface $collector
*
- * @return \Illuminate\Http\JsonResponse
+ * @return JsonResponse
*/
- public function allTransactionJournals(JournalCollectorInterface $collector)
+ public function allTransactionJournals(JournalCollectorInterface $collector): JsonResponse
{
$collector->setLimit(250)->setPage(1);
$return = array_unique($collector->getJournals()->pluck('description')->toArray());
@@ -80,9 +81,9 @@ class AutoCompleteController extends Controller
*
* @param BillRepositoryInterface $repository
*
- * @return \Illuminate\Http\JsonResponse
+ * @return JsonResponse
*/
- public function bills(BillRepositoryInterface $repository)
+ public function bills(BillRepositoryInterface $repository): JsonResponse
{
$return = array_unique(
$repository->getActiveBills()->pluck('name')->toArray()
@@ -95,7 +96,7 @@ class AutoCompleteController extends Controller
/**
* @param BudgetRepositoryInterface $repository
*
- * @return \Illuminate\Http\JsonResponse
+ * @return JsonResponse
*/
public function budgets(BudgetRepositoryInterface $repository)
{
@@ -110,7 +111,7 @@ class AutoCompleteController extends Controller
*
* @param CategoryRepositoryInterface $repository
*
- * @return \Illuminate\Http\JsonResponse
+ * @return JsonResponse
*/
public function categories(CategoryRepositoryInterface $repository)
{
@@ -123,7 +124,7 @@ class AutoCompleteController extends Controller
/**
* @param CurrencyRepositoryInterface $repository
*
- * @return \Illuminate\Http\JsonResponse
+ * @return JsonResponse
*/
public function currencyNames(CurrencyRepositoryInterface $repository)
{
@@ -138,7 +139,7 @@ class AutoCompleteController extends Controller
*
* @param AccountRepositoryInterface $repository
*
- * @return \Illuminate\Http\JsonResponse
+ * @return JsonResponse
*/
public function expenseAccounts(AccountRepositoryInterface $repository)
{
@@ -163,7 +164,7 @@ class AutoCompleteController extends Controller
* @param JournalCollectorInterface $collector
* @param TransactionJournal $except
*
- * @return \Illuminate\Http\JsonResponse|mixed
+ * @return JsonResponse|mixed
*/
public function journalsWithId(JournalCollectorInterface $collector, TransactionJournal $except)
{
@@ -195,7 +196,7 @@ class AutoCompleteController extends Controller
/**
* @param AccountRepositoryInterface $repository
*
- * @return \Illuminate\Http\JsonResponse
+ * @return JsonResponse
*/
public function revenueAccounts(AccountRepositoryInterface $repository)
{
@@ -220,7 +221,7 @@ class AutoCompleteController extends Controller
*
* @param TagRepositoryInterface $tagRepository
*
- * @return \Illuminate\Http\JsonResponse
+ * @return JsonResponse
*/
public function tags(TagRepositoryInterface $tagRepository)
{
@@ -234,7 +235,7 @@ class AutoCompleteController extends Controller
* @param JournalCollectorInterface $collector
* @param string $what
*
- * @return \Illuminate\Http\JsonResponse
+ * @return JsonResponse
*/
public function transactionJournals(JournalCollectorInterface $collector, string $what)
{
@@ -251,7 +252,7 @@ class AutoCompleteController extends Controller
/**
* @param JournalRepositoryInterface $repository
*
- * @return \Illuminate\Http\JsonResponse
+ * @return JsonResponse
*/
public function transactionTypes(JournalRepositoryInterface $repository)
{
diff --git a/app/Http/Controllers/PiggyBankController.php b/app/Http/Controllers/PiggyBankController.php
index 12a56e79c6..fbfbf94505 100644
--- a/app/Http/Controllers/PiggyBankController.php
+++ b/app/Http/Controllers/PiggyBankController.php
@@ -30,6 +30,7 @@ use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
use FireflyIII\Transformers\AccountTransformer;
use FireflyIII\Transformers\PiggyBankTransformer;
+use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection;
@@ -215,6 +216,7 @@ class PiggyBankController extends Controller
*/
public function index(Request $request)
{
+ $this->piggyRepos->correctOrder();
$collection = $this->piggyRepos->getPiggyBanks();
$total = $collection->count();
$page = 0 === (int)$request->get('page') ? 1 : (int)$request->get('page');
@@ -261,27 +263,6 @@ class PiggyBankController extends Controller
return view('piggy-banks.index', compact('piggyBanks', 'accounts'));
}
- /**
- * @param Request $request
- *
- * @return \Illuminate\Http\JsonResponse
- */
- public function order(Request $request)
- {
- $data = $request->get('order');
-
- // set all users piggy banks to zero:
- $this->piggyRepos->reset();
-
- if (\is_array($data)) {
- foreach ($data as $order => $id) {
- $this->piggyRepos->setOrder((int)$id, $order + 1);
- }
- }
-
- return response()->json(['result' => 'ok']);
- }
-
/**
* @param Request $request
* @param PiggyBank $piggyBank
@@ -402,6 +383,20 @@ class PiggyBankController extends Controller
return view('piggy-banks.remove-mobile', compact('piggyBank', 'repetition', 'currency'));
}
+ /**
+ * @param Request $request
+ * @param PiggyBank $piggyBank
+ *
+ * @return JsonResponse
+ */
+ public function setOrder(Request $request, PiggyBank $piggyBank): JsonResponse
+ {
+ $newOrder = (int)$request->get('order');
+ $this->piggyRepos->setOrder($piggyBank, $newOrder);
+
+ return response()->json(['data' => 'OK']);
+ }
+
/**
* @param PiggyBank $piggyBank
*
@@ -409,11 +404,17 @@ class PiggyBankController extends Controller
*/
public function show(PiggyBank $piggyBank)
{
- $note = $piggyBank->notes()->first();
- $events = $this->piggyRepos->getEvents($piggyBank);
- $subTitle = $piggyBank->name;
+ /** @var Carbon $end */
+ $end = session('end', Carbon::now()->endOfMonth());
+ // transform piggies using the transformer:
+ $parameters = new ParameterBag;
+ $parameters->set('end', $end);
+ $transformer = new PiggyBankTransformer(new ParameterBag);
+ $piggy = $transformer->transform($piggyBank);
+ $events = $this->piggyRepos->getEvents($piggyBank);
+ $subTitle = $piggyBank->name;
- return view('piggy-banks.show', compact('piggyBank', 'events', 'subTitle', 'note'));
+ return view('piggy-banks.show', compact('piggyBank', 'events', 'subTitle', 'piggy'));
}
/**
diff --git a/app/Http/Controllers/ProfileController.php b/app/Http/Controllers/ProfileController.php
index 12c9923f6c..581f88b35d 100644
--- a/app/Http/Controllers/ProfileController.php
+++ b/app/Http/Controllers/ProfileController.php
@@ -424,7 +424,7 @@ class ProfileController extends Controller
/**
*
*/
- private function createOAuthKeys()
+ private function createOAuthKeys(): void
{
$rsa = new RSA();
$keys = $rsa->createKey(4096);
@@ -437,11 +437,13 @@ class ProfileController extends Controller
if (file_exists($publicKey) || file_exists($privateKey)) {
return;
}
+ // @codeCoverageIgnoreStart
Log::alert('NO OAuth keys were found. They have been created.');
file_put_contents($publicKey, array_get($keys, 'publickey'));
file_put_contents($privateKey, array_get($keys, 'privatekey'));
}
+ // @codeCoverageIgnoreEnd
/**
* @return string
diff --git a/app/Http/Controllers/RuleController.php b/app/Http/Controllers/RuleController.php
index 3e5b4e5fba..98a781017c 100644
--- a/app/Http/Controllers/RuleController.php
+++ b/app/Http/Controllers/RuleController.php
@@ -102,7 +102,6 @@ class RuleController extends Controller
$preFilled = [
'strict' => true,
];
- $groups = ExpandedForm::makeSelectList($this->ruleGroupRepos->get());
$oldTriggers = [];
$oldActions = [];
$returnToBill = false;
@@ -150,7 +149,7 @@ class RuleController extends Controller
return view(
'rules.rule.create',
compact(
- 'subTitleIcon', 'oldTriggers', 'returnToBill', 'groups', 'preFilled', 'bill', 'oldActions', 'triggerCount', 'actionCount', 'ruleGroup',
+ 'subTitleIcon', 'oldTriggers', 'returnToBill', 'preFilled', 'bill', 'oldActions', 'triggerCount', 'actionCount', 'ruleGroup',
'subTitle'
)
);
@@ -212,7 +211,6 @@ class RuleController extends Controller
*/
public function edit(Request $request, Rule $rule)
{
- $ruleGroups = ExpandedForm::makeSelectList($this->ruleGroupRepos->get());
$triggerCount = 0;
$actionCount = 0;
$oldActions = [];
@@ -243,7 +241,7 @@ class RuleController extends Controller
}
session()->forget('rules.edit.fromUpdate');
- return view('rules.rule.edit', compact('rule', 'subTitle', 'primaryTrigger', 'oldTriggers', 'oldActions', 'triggerCount', 'actionCount', 'ruleGroups'));
+ return view('rules.rule.edit', compact('rule', 'subTitle', 'primaryTrigger', 'oldTriggers', 'oldActions', 'triggerCount', 'actionCount'));
}
/**
@@ -333,14 +331,11 @@ class RuleController extends Controller
public function selectTransactions(Rule $rule)
{
// does the user have shared accounts?
- $accounts = $this->accountRepos->getAccountsByType([AccountType::ASSET]);
- $accountList = ExpandedForm::makeSelectList($accounts);
- $checkedAccounts = array_keys($accountList);
$first = session('first')->format('Y-m-d');
$today = Carbon::create()->format('Y-m-d');
$subTitle = (string)trans('firefly.apply_rule_selection', ['title' => $rule->title]);
- return view('rules.rule.select-transactions', compact('checkedAccounts', 'accountList', 'first', 'today', 'rule', 'subTitle'));
+ return view('rules.rule.select-transactions', compact( 'first', 'today', 'rule', 'subTitle'));
}
/**
@@ -357,12 +352,12 @@ class RuleController extends Controller
// redirect to show bill.
if ($request->get('return_to_bill') === 'true' && (int)$request->get('bill_id') > 0) {
- return redirect(route('bills.show', [(int)$request->get('bill_id')]));
+ return redirect(route('bills.show', [(int)$request->get('bill_id')])); // @codeCoverageIgnore
}
// redirect to new bill creation.
if ((int)$request->get('bill_id') > 0) {
- return redirect($this->getPreviousUri('bills.create.uri'));
+ return redirect($this->getPreviousUri('bills.create.uri')); // @codeCoverageIgnore
}
@@ -408,10 +403,12 @@ class RuleController extends Controller
$matcher->setTriggers($triggers);
try {
$matchingTransactions = $matcher->findTransactionsByTriggers();
+ // @codeCoverageIgnoreStart
} catch (FireflyException $exception) {
Log::error(sprintf('Could not grab transactions in testTriggers(): %s', $exception->getMessage()));
Log::error($exception->getTraceAsString());
}
+ // @codeCoverageIgnoreStart
// Warn the user if only a subset of transactions is returned
@@ -427,10 +424,12 @@ class RuleController extends Controller
$view = 'ERROR, see logs.';
try {
$view = view('list.journals-tiny', ['transactions' => $matchingTransactions])->render();
+ // @codeCoverageIgnoreStart
} catch (Throwable $exception) {
Log::error(sprintf('Could not render view in testTriggers(): %s', $exception->getMessage()));
Log::error($exception->getTraceAsString());
}
+ // @codeCoverageIgnoreEnd
return response()->json(['html' => $view, 'warning' => $warning]);
}
@@ -466,10 +465,12 @@ class RuleController extends Controller
$matcher->setRule($rule);
try {
$matchingTransactions = $matcher->findTransactionsByRule();
+ // @codeCoverageIgnoreStart
} catch (FireflyException $exception) {
Log::error(sprintf('Could not grab transactions in testTriggersByRule(): %s', $exception->getMessage()));
Log::error($exception->getTraceAsString());
}
+ // @codeCoverageIgnoreEnd
// Warn the user if only a subset of transactions is returned
$warning = '';
@@ -484,10 +485,12 @@ class RuleController extends Controller
$view = 'ERROR, see logs.';
try {
$view = view('list.journals-tiny', ['transactions' => $matchingTransactions])->render();
+ // @codeCoverageIgnoreStart
} catch (Throwable $exception) {
Log::error(sprintf('Could not render view in testTriggersByRule(): %s', $exception->getMessage()));
Log::error($exception->getTraceAsString());
}
+ // @codeCoverageIgnoreEnd
return response()->json(['html' => $view, 'warning' => $warning]);
}
@@ -592,10 +595,12 @@ class RuleController extends Controller
'count' => 1,
]
)->render();
+ // @codeCoverageIgnoreStart
} catch (Throwable $e) {
Log::error(sprintf('Throwable was thrown in getActionsForBill(): %s', $e->getMessage()));
Log::error($e->getTraceAsString());
}
+ // @codeCoverageIgnoreEnd
return $actions;
}
@@ -625,10 +630,12 @@ class RuleController extends Controller
'count' => $count,
]
)->render();
+ // @codeCoverageIgnoreStart
} catch (Throwable $e) {
Log::debug(sprintf('Throwable was thrown in getCurrentActions(): %s', $e->getMessage()));
Log::error($e->getTraceAsString());
}
+ // @codeCoverageIgnoreEnd
++$index;
}
@@ -660,10 +667,12 @@ class RuleController extends Controller
'count' => $count,
]
)->render();
+ // @codeCoverageIgnoreStart
} catch (Throwable $e) {
Log::debug(sprintf('Throwable was thrown in getCurrentTriggers(): %s', $e->getMessage()));
Log::error($e->getTraceAsString());
}
+ // @codeCoverageIgnoreEnd
++$index;
}
}
@@ -696,10 +705,12 @@ class RuleController extends Controller
'count' => $count,
]
)->render();
+ // @codeCoverageIgnoreStart
} catch (Throwable $e) {
Log::debug(sprintf('Throwable was thrown in getPreviousActions(): %s', $e->getMessage()));
Log::error($e->getTraceAsString());
}
+ // @codeCoverageIgnoreEnd
++$newIndex;
}
@@ -732,10 +743,12 @@ class RuleController extends Controller
'count' => $count,
]
)->render();
+ // @codeCoverageIgnoreStart
} catch (Throwable $e) {
Log::debug(sprintf('Throwable was thrown in getPreviousTriggers(): %s', $e->getMessage()));
Log::error($e->getTraceAsString());
}
+ // @codeCoverageIgnoreEnd
++$newIndex;
}
@@ -791,10 +804,12 @@ class RuleController extends Controller
'count' => 4,
]
)->render();
+ // @codeCoverageIgnoreStart
} catch (Throwable $e) {
Log::debug(sprintf('Throwable was thrown in getTriggersForBill(): %s', $e->getMessage()));
Log::debug($e->getTraceAsString());
}
+ // @codeCoverageIgnoreEnd
return $triggers;
}
diff --git a/app/Http/Controllers/RuleGroupController.php b/app/Http/Controllers/RuleGroupController.php
index 16c44dea94..360f73eb82 100644
--- a/app/Http/Controllers/RuleGroupController.php
+++ b/app/Http/Controllers/RuleGroupController.php
@@ -23,11 +23,9 @@ declare(strict_types=1);
namespace FireflyIII\Http\Controllers;
use Carbon\Carbon;
-use ExpandedForm;
use FireflyIII\Http\Requests\RuleGroupFormRequest;
use FireflyIII\Http\Requests\SelectTransactionsRequest;
use FireflyIII\Jobs\ExecuteRuleGroupOnExistingTransactions;
-use FireflyIII\Models\AccountType;
use FireflyIII\Models\RuleGroup;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\RuleGroup\RuleGroupRepositoryInterface;
@@ -75,22 +73,18 @@ class RuleGroupController extends Controller
}
/**
- * @param RuleGroupRepositoryInterface $repository
- * @param RuleGroup $ruleGroup
+ * @param RuleGroup $ruleGroup
*
* @return View
*/
- public function delete(RuleGroupRepositoryInterface $repository, RuleGroup $ruleGroup)
+ public function delete(RuleGroup $ruleGroup)
{
$subTitle = trans('firefly.delete_rule_group', ['title' => $ruleGroup->title]);
- $ruleGroupList = ExpandedForm::makeSelectListWithEmpty($repository->get());
- unset($ruleGroupList[$ruleGroup->id]);
-
// put previous url in session
$this->rememberPreviousUri('rule-groups.delete.uri');
- return view('rules.rule-group.delete', compact('ruleGroup', 'subTitle', 'ruleGroupList'));
+ return view('rules.rule-group.delete', compact('ruleGroup', 'subTitle'));
}
/**
@@ -135,11 +129,17 @@ class RuleGroupController extends Controller
{
$subTitle = trans('firefly.edit_rule_group', ['title' => $ruleGroup->title]);
+ $preFilled = [
+ 'active' => $ruleGroup->active,
+ ];
+
+
// put previous url in session if not redirect from store (not "return_to_edit").
if (true !== session('rule-groups.edit.fromUpdate')) {
$this->rememberPreviousUri('rule-groups.edit.uri');
}
session()->forget('rule-groups.edit.fromUpdate');
+ session()->flash('preFilled', $preFilled);
return view('rules.rule-group.edit', compact('ruleGroup', 'subTitle'));
}
@@ -179,22 +179,17 @@ class RuleGroupController extends Controller
}
/**
- * @param AccountRepositoryInterface $repository
- * @param RuleGroup $ruleGroup
+ * @param RuleGroup $ruleGroup
*
* @return View
*/
- public function selectTransactions(AccountRepositoryInterface $repository, RuleGroup $ruleGroup)
+ public function selectTransactions(RuleGroup $ruleGroup)
{
- // does the user have shared accounts?
- $accounts = $repository->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET]);
- $accountList = ExpandedForm::makeSelectList($accounts);
- $checkedAccounts = array_keys($accountList);
- $first = session('first')->format('Y-m-d');
- $today = Carbon::create()->format('Y-m-d');
- $subTitle = (string)trans('firefly.apply_rule_group_selection', ['title' => $ruleGroup->title]);
+ $first = session('first')->format('Y-m-d');
+ $today = Carbon::create()->format('Y-m-d');
+ $subTitle = (string)trans('firefly.apply_rule_group_selection', ['title' => $ruleGroup->title]);
- return view('rules.rule-group.select-transactions', compact('checkedAccounts', 'accountList', 'first', 'today', 'ruleGroup', 'subTitle'));
+ return view('rules.rule-group.select-transactions', compact('first', 'today', 'ruleGroup', 'subTitle'));
}
/**
diff --git a/app/Http/Controllers/System/InstallController.php b/app/Http/Controllers/System/InstallController.php
index a84a03b1e0..9945f9d4d9 100644
--- a/app/Http/Controllers/System/InstallController.php
+++ b/app/Http/Controllers/System/InstallController.php
@@ -33,6 +33,7 @@ use Log;
use phpseclib\Crypt\RSA;
/**
+ * @codeCoverageIgnore
* Class InstallController
*/
class InstallController extends Controller
diff --git a/app/Http/Controllers/TagController.php b/app/Http/Controllers/TagController.php
index 294d364014..26074416c4 100644
--- a/app/Http/Controllers/TagController.php
+++ b/app/Http/Controllers/TagController.php
@@ -31,19 +31,10 @@ use FireflyIII\Repositories\Tag\TagRepositoryInterface;
use FireflyIII\Support\CacheProperties;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
-use Preferences;
use View;
/**
* Class TagController.
- *
- * Remember: a balancingAct takes at most one expense and one transfer.
- * an advancePayment takes at most one expense, infinite deposits and NO transfers.
- *
- * transaction can only have one advancePayment OR balancingAct.
- * Other attempts to put in such a tag are blocked.
- * also show an error when editing a tag and it becomes either
- * of these two types. Or rather, block editing of the tag.
*/
class TagController extends Controller
{
@@ -79,7 +70,6 @@ class TagController extends Controller
{
$subTitle = trans('firefly.new_tag');
$subTitleIcon = 'fa-tag';
- $apiKey = env('GOOGLE_MAPS_API_KEY', '');
// put previous url in session if not redirect from store (not "create another").
if (true !== session('tags.create.fromStore')) {
@@ -87,7 +77,7 @@ class TagController extends Controller
}
session()->forget('tags.create.fromStore');
- return view('tags.create', compact('subTitle', 'subTitleIcon', 'apiKey'));
+ return view('tags.create', compact('subTitle', 'subTitleIcon'));
}
/**
@@ -118,7 +108,7 @@ class TagController extends Controller
$this->repository->destroy($tag);
session()->flash('success', (string)trans('firefly.deleted_tag', ['tag' => $tagName]));
- Preferences::mark();
+ app('preferences')->mark();
return redirect($this->getPreviousUri('tags.delete.uri'));
}
@@ -134,7 +124,6 @@ class TagController extends Controller
{
$subTitle = trans('firefly.edit_tag', ['tag' => $tag->tag]);
$subTitleIcon = 'fa-tag';
- $apiKey = env('GOOGLE_MAPS_API_KEY', '');
// put previous url in session if not redirect from store (not "return_to_edit").
if (true !== session('tags.edit.fromUpdate')) {
@@ -142,7 +131,7 @@ class TagController extends Controller
}
session()->forget('tags.edit.fromUpdate');
- return view('tags.edit', compact('tag', 'subTitle', 'subTitleIcon', 'apiKey'));
+ return view('tags.edit', compact('tag', 'subTitle', 'subTitleIcon'));
}
/**
@@ -155,27 +144,18 @@ class TagController extends Controller
public function index(TagRepositoryInterface $repository)
{
// start with oldest tag
- $oldestTag = $repository->oldestTag();
- /** @var Carbon $start */
- $start = new Carbon;
- if (null !== $oldestTag) {
- /** @var Carbon $start */
- $start = $oldestTag->date; // @codeCoverageIgnore
- }
- if (null === $oldestTag) {
- /** @var Carbon $start */
- $start = clone session('first');
- }
-
- $now = new Carbon;
+ $oldestTagDate = null === $repository->oldestTag() ? clone session('first') : $repository->oldestTag()->date;
+ $newestTagDate = null === $repository->newestTag() ? new Carbon : $repository->newestTag()->date;
+ $oldestTagDate->startOfYear();
+ $newestTagDate->endOfYear();
$clouds = [];
$clouds['no-date'] = $repository->tagCloud(null);
- while ($now > $start) {
- $year = $now->year;
+ while ($newestTagDate > $oldestTagDate) {
+ $year = $newestTagDate->year;
$clouds[$year] = $repository->tagCloud($year);
- $now->subYear();
+ $newestTagDate->subYear();
}
$count = $repository->count();
@@ -196,12 +176,11 @@ class TagController extends Controller
$subTitle = $tag->tag;
$subTitleIcon = 'fa-tag';
$page = (int)$request->get('page');
- $pageSize = (int)Preferences::get('listPageSize', 50)->data;
- $range = Preferences::get('viewRange', '1M')->data;
+ $pageSize = (int)app('preferences')->get('listPageSize', 50)->data;
+ $range = app('preferences')->get('viewRange', '1M')->data;
$start = null;
$end = null;
$periods = new Collection;
- $apiKey = env('GOOGLE_MAPS_API_KEY', '');
$path = route('tags.show', [$tag->id]);
// prep for "all" view.
@@ -213,7 +192,7 @@ class TagController extends Controller
}
// prep for "specific date" view.
- if (\strlen($moment) > 0 && 'all' !== $moment) {
+ if ('all' !== $moment && \strlen($moment) > 0) {
$start = new Carbon($moment);
$end = app('navigation')->endOfPeriod($start, $range);
$subTitle = trans(
@@ -226,7 +205,7 @@ class TagController extends Controller
}
// prep for current period
- if (0 === \strlen($moment)) {
+ if ('' === $moment) {
/** @var Carbon $start */
$start = clone session('start', app('navigation')->startOfPeriod(new Carbon, $range));
/** @var Carbon $end */
@@ -261,7 +240,7 @@ class TagController extends Controller
$this->repository->store($data);
session()->flash('success', (string)trans('firefly.created_tag', ['tag' => $data['tag']]));
- Preferences::mark();
+ app('preferences')->mark();
if (1 === (int)$request->get('create_another')) {
// @codeCoverageIgnoreStart
@@ -286,7 +265,7 @@ class TagController extends Controller
$this->repository->update($tag, $data);
session()->flash('success', (string)trans('firefly.updated_tag', ['tag' => $data['tag']]));
- Preferences::mark();
+ app('preferences')->mark();
if (1 === (int)$request->get('return_to_edit')) {
// @codeCoverageIgnoreStart
@@ -308,9 +287,11 @@ class TagController extends Controller
private function getPeriodOverview(Tag $tag): Collection
{
// get first and last tag date from tag:
- $range = Preferences::get('viewRange', '1M')->data;
- $start = app('navigation')->startOfPeriod($this->repository->firstUseDate($tag), $range);
- $end = app('navigation')->startOfPeriod($this->repository->lastUseDate($tag), $range);
+ $range = app('preferences')->get('viewRange', '1M')->data;
+ $end = app('navigation')->endOfX($this->repository->lastUseDate($tag), $range, null);
+ $start = $this->repository->firstUseDate($tag);
+
+
// properties for entries with their amounts.
$cache = new CacheProperties;
$cache->addProperty($start);
@@ -323,22 +304,23 @@ class TagController extends Controller
}
$collection = new Collection;
-
+ $currentEnd = clone $end;
// while end larger or equal to start
- while ($end >= $start) {
- $currentEnd = app('navigation')->endOfPeriod($end, $range);
+ while ($currentEnd >= $start) {
+ $currentStart = app('navigation')->startOfPeriod($currentEnd, $range);
// get expenses and what-not in this period and this tag.
$arr = [
'string' => $end->format('Y-m-d'),
- 'name' => app('navigation')->periodShow($end, $range),
+ 'name' => app('navigation')->periodShow($currentEnd, $range),
'date' => clone $end,
- 'spent' => $this->repository->spentInPeriod($tag, $end, $currentEnd),
- 'earned' => $this->repository->earnedInPeriod($tag, $end, $currentEnd),
+ 'spent' => $this->repository->spentInPeriod($tag, $currentStart, $currentEnd),
+ 'earned' => $this->repository->earnedInPeriod($tag, $currentStart, $currentEnd),
];
$collection->push($arr);
- $end = app('navigation')->subtractPeriod($end, $range, 1);
+ $currentEnd = clone $currentStart;
+ $currentEnd->subDay();
}
$cache->store($collection);
diff --git a/app/Http/Controllers/Transaction/LinkController.php b/app/Http/Controllers/Transaction/LinkController.php
index c238f36f01..686b73c082 100644
--- a/app/Http/Controllers/Transaction/LinkController.php
+++ b/app/Http/Controllers/Transaction/LinkController.php
@@ -107,7 +107,7 @@ class LinkController extends Controller
return redirect(route('transactions.show', [$journal->id]));
}
- $other = $this->journalRepository->find($linkInfo['transaction_journal_id']);
+ $other = $this->journalRepository->findNull($linkInfo['transaction_journal_id']);
$alreadyLinked = $this->repository->findLink($journal, $other);
if ($other->id === $journal->id) {
diff --git a/app/Http/Controllers/Transaction/MassController.php b/app/Http/Controllers/Transaction/MassController.php
index e404300f61..8b78a9ccb9 100644
--- a/app/Http/Controllers/Transaction/MassController.php
+++ b/app/Http/Controllers/Transaction/MassController.php
@@ -25,6 +25,7 @@ namespace FireflyIII\Http\Controllers\Transaction;
use Carbon\Carbon;
use FireflyIII\Helpers\Collector\JournalCollectorInterface;
use FireflyIII\Helpers\Filter\NegativeAmountFilter;
+use FireflyIII\Helpers\Filter\TransactionViewFilter;
use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Http\Requests\MassDeleteJournalRequest;
use FireflyIII\Http\Requests\MassEditJournalRequest;
@@ -145,22 +146,24 @@ class MassController extends Controller
$collector->setUser(auth()->user());
$collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation();
$collector->setJournals($journals);
- $collector->addFilter(NegativeAmountFilter::class);
- $transactions = $collector->getJournals();
+ $collector->addFilter(TransactionViewFilter::class);
+ $collection = $collector->getJournals();
// add some filters:
// transform to array
- $journals = $transactions->map(
+ $transactions = $collection->map(
function (Transaction $transaction) use ($transformer) {
- $result = $transformer->transform($transaction);
-
- return $result;
+ $transaction= $transformer->transform($transaction);
+ // make sure amount is positive:
+ $transaction['amount'] = app('steam')->positive((string)$transaction['amount']);
+ $transaction['foreign_amount'] = app('steam')->positive((string)$transaction['foreign_amount']);
+ return $transaction;
}
);
- return view('transactions.mass.edit', compact('journals', 'subTitle', 'accounts', 'budgets'));
+ return view('transactions.mass.edit', compact('transactions', 'subTitle', 'accounts', 'budgets'));
}
/**
diff --git a/app/Http/Controllers/Transaction/SplitController.php b/app/Http/Controllers/Transaction/SplitController.php
index 2dfc57325c..aa25f47fdc 100644
--- a/app/Http/Controllers/Transaction/SplitController.php
+++ b/app/Http/Controllers/Transaction/SplitController.php
@@ -29,8 +29,6 @@ use FireflyIII\Helpers\Attachments\AttachmentHelperInterface;
use FireflyIII\Helpers\Collector\JournalCollectorInterface;
use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Http\Requests\SplitJournalFormRequest;
-use FireflyIII\Models\Account;
-use FireflyIII\Models\AccountType;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionType;
@@ -100,22 +98,18 @@ class SplitController extends Controller
if ($this->isOpeningBalance($journal)) {
return $this->redirectToAccount($journal); // @codeCoverageIgnore
}
+ // basic fields:
+ $uploadSize = min(Steam::phpBytes(ini_get('upload_max_filesize')), Steam::phpBytes(ini_get('post_max_size')));
+ $subTitle = trans('breadcrumbs.edit_journal', ['description' => $journal->description]);
+ $subTitleIcon = 'fa-pencil';
- $uploadSize = min(Steam::phpBytes(ini_get('upload_max_filesize')), Steam::phpBytes(ini_get('post_max_size')));
- $currencies = $this->currencies->get();
+ // lists and collections
+ $currencies = $this->currencies->get();
+ $budgets = ExpandedForm::makeSelectListWithEmpty($this->budgets->getActiveBudgets());
+
+ // other fields
$optionalFields = Preferences::get('transaction_journal_optional_fields', [])->data;
- $budgets = ExpandedForm::makeSelectListWithEmpty($this->budgets->getActiveBudgets());
$preFilled = $this->arrayFromJournal($request, $journal);
- $subTitle = trans('breadcrumbs.edit_journal', ['description' => $journal->description]);
- $subTitleIcon = 'fa-pencil';
- $accountList = $this->accounts->getAccountsByType([AccountType::ASSET, AccountType::DEFAULT]);
- $accountArray = [];
- // account array to display currency info:
- /** @var Account $account */
- foreach ($accountList as $account) {
- $accountArray[$account->id] = $account;
- $accountArray[$account->id]['currency_id'] = (int)$this->accounts->getMetaValue($account, 'currency_id');
- }
// put previous url in session if not redirect from store (not "return_to_edit").
if (true !== session('transactions.edit-split.fromUpdate')) {
@@ -126,7 +120,7 @@ class SplitController extends Controller
return view(
'transactions.split.edit', compact(
'subTitleIcon', 'currencies', 'optionalFields', 'preFilled', 'subTitle', 'uploadSize', 'budgets',
- 'journal', 'accountArray'
+ 'journal'
)
);
}
@@ -146,8 +140,7 @@ class SplitController extends Controller
// keep current bill:
$data['bill_id'] = $journal->bill_id;
-
- $journal = $this->repository->update($journal, $data);
+ $journal = $this->repository->update($journal, $data);
/** @var array $files */
$files = $request->hasFile('attachments') ? $request->file('attachments') : null;
@@ -283,9 +276,9 @@ class SplitController extends Controller
}
// take some info from first transaction, that should at least exist.
$array[$index] = $row;
- $array[$index]['currency_id'] = $array[0]['transaction_currency_id'];
- $array[$index]['currency_code'] = $array[0]['transaction_currency_code'] ?? '';
- $array[$index]['currency_symbol'] = $array[0]['transaction_currency_symbol'] ?? '';
+ $array[$index]['currency_id'] = $array[0]['currency_id'];
+ $array[$index]['currency_code'] = $array[0]['currency_code'] ?? '';
+ $array[$index]['currency_symbol'] = $array[0]['currency_symbol'] ?? '';
$array[$index]['foreign_amount'] = round($array[0]['foreign_destination_amount'] ?? '0', 12);
$array[$index]['foreign_currency_id'] = $array[0]['foreign_currency_id'];
$array[$index]['foreign_currency_code'] = $array[0]['foreign_currency_code'];
diff --git a/app/Http/Middleware/Authenticate.php b/app/Http/Middleware/Authenticate.php
index 394f04d01a..9c2b7f0131 100644
--- a/app/Http/Middleware/Authenticate.php
+++ b/app/Http/Middleware/Authenticate.php
@@ -1,5 +1,4 @@
.
*/
+declare(strict_types=1);
+
namespace FireflyIII\Http\Middleware;
use Closure;
@@ -103,7 +104,9 @@ class Authenticate
}
}
} catch (QueryException $e) {
+ // @codeCoverageIgnoreStart
throw new FireflyException('It seems the database has not yet been initialized. Did you run the correct upgrade or installation commands?');
+ // @codeCoverageIgnoreEnd
}
return $this->auth->authenticate();
diff --git a/app/Http/Middleware/Installer.php b/app/Http/Middleware/Installer.php
index 1afa004cdf..2f8f73a654 100644
--- a/app/Http/Middleware/Installer.php
+++ b/app/Http/Middleware/Installer.php
@@ -1,4 +1,25 @@
.
+ */
+
declare(strict_types=1);
namespace FireflyIII\Http\Middleware;
diff --git a/app/Http/Requests/SplitJournalFormRequest.php b/app/Http/Requests/SplitJournalFormRequest.php
index 207754df5b..ce99023a1f 100644
--- a/app/Http/Requests/SplitJournalFormRequest.php
+++ b/app/Http/Requests/SplitJournalFormRequest.php
@@ -109,23 +109,23 @@ class SplitJournalFormRequest extends Request
public function rules(): array
{
return [
- 'what' => 'required|in:withdrawal,deposit,transfer',
- 'journal_description' => 'required|between:1,255',
- 'id' => 'numeric|belongsToUser:transaction_journals,id',
- 'journal_source_account_id' => 'numeric|belongsToUser:accounts,id',
- 'journal_source_account_name.*' => 'between:1,255',
- 'journal_currency_id' => 'required|exists:transaction_currencies,id',
- 'date' => 'required|date',
- 'interest_date' => 'date|nullable',
- 'book_date' => 'date|nullable',
- 'process_date' => 'date|nullable',
- 'transactions.*.transaction_description' => 'required|between:1,255',
- 'transactions.*.destination_account_id' => 'numeric|belongsToUser:accounts,id',
- 'transactions.*.destination_name' => 'between:1,255|nullable',
- 'transactions.*.amount' => 'required|numeric',
- 'transactions.*.budget_id' => 'belongsToUser:budgets,id',
- 'transactions.*.category_name' => 'between:1,255|nullable',
- 'transactions.*.piggy_bank_id' => 'between:1,255|nullable',
+ 'what' => 'required|in:withdrawal,deposit,transfer',
+ 'journal_description' => 'required|between:1,255',
+ 'id' => 'numeric|belongsToUser:transaction_journals,id',
+ 'journal_source_account_id' => 'numeric|belongsToUser:accounts,id',
+ 'journal_source_account_name.*' => 'between:1,255',
+ 'journal_currency_id' => 'required|exists:transaction_currencies,id',
+ 'date' => 'required|date',
+ 'interest_date' => 'date|nullable',
+ 'book_date' => 'date|nullable',
+ 'process_date' => 'date|nullable',
+ 'transactions.*.transaction_description' => 'required|between:1,255',
+ 'transactions.*.destination_account_id' => 'numeric|belongsToUser:accounts,id',
+ 'transactions.*.destination_name' => 'between:1,255|nullable',
+ 'transactions.*.amount' => 'required|numeric',
+ 'transactions.*.budget_id' => 'belongsToUser:budgets,id',
+ 'transactions.*.category_name' => 'between:1,255|nullable',
+ 'transactions.*.piggy_bank_id' => 'between:1,255|nullable',
];
}
diff --git a/app/Import/Configuration/BunqConfigurator.php b/app/Import/Configuration/BunqConfigurator.php
index 910c494d71..a115f8e933 100644
--- a/app/Import/Configuration/BunqConfigurator.php
+++ b/app/Import/Configuration/BunqConfigurator.php
@@ -29,6 +29,8 @@ use FireflyIII\Support\Import\Configuration\Bunq\HaveAccounts;
use Log;
/**
+ * @deprecated
+ * @codeCoverageIgnore
* Class BunqConfigurator.
*/
class BunqConfigurator implements ConfiguratorInterface
diff --git a/app/Import/Configuration/ConfiguratorInterface.php b/app/Import/Configuration/ConfiguratorInterface.php
index f171044f7c..a1e961b0ec 100644
--- a/app/Import/Configuration/ConfiguratorInterface.php
+++ b/app/Import/Configuration/ConfiguratorInterface.php
@@ -25,6 +25,8 @@ namespace FireflyIII\Import\Configuration;
use FireflyIII\Models\ImportJob;
/**
+ * @deprecated
+ * @codeCoverageIgnore
* Interface ConfiguratorInterface.
*/
interface ConfiguratorInterface
diff --git a/app/Import/Configuration/FileConfigurator.php b/app/Import/Configuration/FileConfigurator.php
deleted file mode 100644
index 4d98232d2a..0000000000
--- a/app/Import/Configuration/FileConfigurator.php
+++ /dev/null
@@ -1,275 +0,0 @@
-.
- */
-declare(strict_types=1);
-
-namespace FireflyIII\Import\Configuration;
-
-use FireflyIII\Exceptions\FireflyException;
-use FireflyIII\Models\ImportJob;
-use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
-use FireflyIII\Support\Import\Configuration\ConfigurationInterface;
-use FireflyIII\Support\Import\Configuration\File\Initial;
-use FireflyIII\Support\Import\Configuration\File\Map;
-use FireflyIII\Support\Import\Configuration\File\Roles;
-use FireflyIII\Support\Import\Configuration\File\UploadConfig;
-use Log;
-
-/**
- * Class FileConfigurator.
- */
-class FileConfigurator implements ConfiguratorInterface
-{
- /** @var array */
- private $defaultConfig
- = [
- 'stage' => 'initial',
- 'has-headers' => false, // assume
- 'date-format' => 'Ymd', // assume
- 'delimiter' => ',', // assume
- 'import-account' => 0, // none,
- 'specifics' => [], // none
- 'column-count' => 0, // unknown
- 'column-roles' => [], // unknown
- 'column-do-mapping' => [], // not yet set which columns must be mapped
- 'column-mapping-config' => [], // no mapping made yet.
- 'file-type' => 'csv', // assume
- 'has-config-file' => true,
- 'apply-rules' => true,
- 'auto-start' => false,
- ];
- /** @var ImportJob */
- private $job;
- /** @var ImportJobRepositoryInterface */
- private $repository;
-
- // give job default config:
- /** @var string */
- private $warning = '';
-
- /**
- * FileConfigurator constructor.
- */
- public function __construct()
- {
- Log::debug('Created FileConfigurator');
- }
-
- /**
- * Store any data from the $data array into the job.
- *
- * @param array $data
- *
- * @return bool
- *
- * @throws FireflyException
- */
- public function configureJob(array $data): bool
- {
- if (null === $this->job) {
- throw new FireflyException('Cannot call configureJob() without a job.');
- }
- /** @var ConfigurationInterface $object */
- $object = app($this->getConfigurationClass());
- $object->setJob($this->job);
- $result = $object->storeConfiguration($data);
- $this->warning = $object->getWarningMessage();
-
- return $result;
- }
-
- /**
- * Return the data required for the next step in the job configuration.
- *
- * @return array
- *
- * @throws FireflyException
- */
- public function getNextData(): array
- {
- if (null === $this->job) {
- throw new FireflyException('Cannot call getNextData() without a job.');
- }
- /** @var ConfigurationInterface $object */
- $object = app($this->getConfigurationClass());
- $object->setJob($this->job);
-
- return $object->getData();
- }
-
- /**
- * @return string
- *
- * @throws FireflyException
- */
- public function getNextView(): string
- {
- if (null === $this->job) {
- throw new FireflyException('Cannot call getNextView() without a job.');
- }
- $config = $this->getConfig();
- $stage = $config['stage'] ?? 'initial';
- switch ($stage) {
- case 'initial': // has nothing, no file upload or anything.
- return 'import.file.initial';
- case 'upload-config': // has file, needs file config.
- return 'import.file.upload-config';
- case 'roles': // has configured file, needs roles.
- return 'import.file.roles';
- case 'map': // has roles, needs mapping.
- return 'import.file.map';
- }
- throw new FireflyException(sprintf('No view for stage "%s"', $stage));
- }
-
- /**
- * Return possible warning to user.
- *
- * @return string
- *
- * @throws FireflyException
- */
- public function getWarningMessage(): string
- {
- if (null === $this->job) {
- throw new FireflyException('Cannot call getWarningMessage() without a job.');
- }
-
- return $this->warning;
- }
-
- /**
- * @return bool
- *
- * @throws FireflyException
- */
- public function isJobConfigured(): bool
- {
- if (null === $this->job) {
- throw new FireflyException('Cannot call isJobConfigured() without a job.');
- }
- $config = $this->getConfig();
- $stage = $config['stage'] ?? 'initial';
- if ('ready' === $stage) {
- Log::debug('isJobConfigured returns true');
-
- return true;
- }
- Log::debug('isJobConfigured returns false');
-
- return false;
- }
-
- /**
- * @param ImportJob $job
- */
- public function setJob(ImportJob $job)
- {
- Log::debug(sprintf('FileConfigurator::setJob(#%d: %s)', $job->id, $job->key));
- $this->job = $job;
- $this->repository = app(ImportJobRepositoryInterface::class);
- $this->repository->setUser($job->user);
-
- // set number of steps to 100:
- $extendedStatus = $this->getExtendedStatus();
- $extendedStatus['steps'] = 6;
- $extendedStatus['done'] = 0;
- $this->setExtendedStatus($extendedStatus);
-
- $config = $this->getConfig();
- $newConfig = array_merge($this->defaultConfig, $config);
- $this->repository->setConfiguration($job, $newConfig);
- }
-
- /**
- * Short hand method.
- *
- * @return array
- */
- private function getConfig(): array
- {
- return $this->repository->getConfiguration($this->job);
- }
-
- /**
- * @return string
- *
- * @throws FireflyException
- */
- private function getConfigurationClass(): string
- {
- $config = $this->getConfig();
- $stage = $config['stage'] ?? 'initial';
- $class = false;
- Log::debug(sprintf('Now in getConfigurationClass() for stage "%s"', $stage));
-
- switch ($stage) {
- case 'initial': // has nothing, no file upload or anything.
- $class = Initial::class;
- break;
- case 'upload-config': // has file, needs file config.
- $class = UploadConfig::class;
- break;
- case 'roles': // has configured file, needs roles.
- $class = Roles::class;
- break;
- case 'map': // has roles, needs mapping.
- $class = Map::class;
- break;
- default:
- break;
- }
-
- if (false === $class || 0 === \strlen($class)) {
- throw new FireflyException(sprintf('Cannot handle job stage "%s" in getConfigurationClass().', $stage));
- }
- if (!class_exists($class)) {
- throw new FireflyException(sprintf('Class %s does not exist in getConfigurationClass().', $class)); // @codeCoverageIgnore
- }
- Log::debug(sprintf('Configuration class is "%s"', $class));
-
- return $class;
- }
-
- /**
- * Shorthand method to return the extended status.
- *
- * @codeCoverageIgnore
- *
- * @return array
- */
- private function getExtendedStatus(): array
- {
- return $this->repository->getExtendedStatus($this->job);
- }
-
- /**
- * Shorthand method to set the extended status.
- *
- * @codeCoverageIgnore
- *
- * @param array $extended
- */
- private function setExtendedStatus(array $extended): void
- {
- $this->repository->setExtendedStatus($this->job, $extended);
-
- }
-}
diff --git a/app/Import/Configuration/SpectreConfigurator.php b/app/Import/Configuration/SpectreConfigurator.php
deleted file mode 100644
index 3f65633d3a..0000000000
--- a/app/Import/Configuration/SpectreConfigurator.php
+++ /dev/null
@@ -1,233 +0,0 @@
-.
- */
-declare(strict_types=1);
-
-namespace FireflyIII\Import\Configuration;
-
-use FireflyIII\Exceptions\FireflyException;
-use FireflyIII\Models\ImportJob;
-use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
-use FireflyIII\Support\Import\Configuration\Spectre\HaveAccounts;
-use Log;
-
-/**
- * Class SpectreConfigurator.
- */
-class SpectreConfigurator implements ConfiguratorInterface
-{
- /** @var ImportJob */
- private $job;
-
- /** @var ImportJobRepositoryInterface */
- private $repository;
-
- /** @var string */
- private $warning = '';
-
- /**
- * ConfiguratorInterface constructor.
- */
- public function __construct()
- {
- }
-
- /**
- * Store any data from the $data array into the job.
- *
- * @param array $data
- *
- * @return bool
- *
- * @throws FireflyException
- */
- public function configureJob(array $data): bool
- {
- if (null === $this->job) {
- throw new FireflyException('Cannot call configureJob() without a job.');
- }
- $stage = $this->getConfig()['stage'] ?? 'initial';
- Log::debug(sprintf('in getNextData(), for stage "%s".', $stage));
- switch ($stage) {
- case 'have-accounts':
- /** @var HaveAccounts $class */
- $class = app(HaveAccounts::class);
- $class->setJob($this->job);
- $class->storeConfiguration($data);
-
- // update job for next step and set to "configured".
- $config = $this->getConfig();
- $config['stage'] = 'have-account-mapping';
- $this->repository->setConfiguration($this->job, $config);
-
- return true;
- default:
- throw new FireflyException(sprintf('Cannot store configuration when job is in state "%s"', $stage));
- break;
- }
- }
-
- /**
- * Return the data required for the next step in the job configuration.
- *
- * @return array
- *
- * @throws FireflyException
- */
- public function getNextData(): array
- {
- if (null === $this->job) {
- throw new FireflyException('Cannot call configureJob() without a job.');
- }
- $config = $this->getConfig();
- $stage = $config['stage'] ?? 'initial';
-
- Log::debug(sprintf('in getNextData(), for stage "%s".', $stage));
- switch ($stage) {
- case 'has-token':
- // simply redirect to Spectre.
- $config['is-redirected'] = true;
- $config['stage'] = 'user-logged-in';
- $status = 'configured';
-
- // update config and status:
- $this->repository->setConfiguration($this->job, $config);
- $this->repository->setStatus($this->job, $status);
-
- return $this->repository->getConfiguration($this->job);
- case 'have-accounts':
- /** @var HaveAccounts $class */
- $class = app(HaveAccounts::class);
- $class->setJob($this->job);
-
- return $class->getData();
- default:
- return [];
- }
- }
-
- /**
- * @return string
- *
- * @throws FireflyException
- */
- public function getNextView(): string
- {
- if (null === $this->job) {
- throw new FireflyException('Cannot call configureJob() without a job.');
- }
- $stage = $this->getConfig()['stage'] ?? 'initial';
- Log::debug(sprintf('in getNextView(), for stage "%s".', $stage));
- switch ($stage) {
- case 'has-token':
- // redirect to Spectre.
- Log::info('User is being redirected to Spectre.');
-
- return 'import.spectre.redirect';
- case 'have-accounts':
- return 'import.spectre.accounts';
- default:
- return '';
- }
- }
-
- /**
- * Return possible warning to user.
- *
- * @return string
- */
- public function getWarningMessage(): string
- {
- return $this->warning;
- }
-
- /**
- * @return bool
- *
- * @throws FireflyException
- */
- public function isJobConfigured(): bool
- {
- if (null === $this->job) {
- throw new FireflyException('Cannot call configureJob() without a job.');
- }
- $stage = $this->getConfig()['stage'] ?? 'initial';
- Log::debug(sprintf('in isJobConfigured(), for stage "%s".', $stage));
- switch ($stage) {
- case 'has-token':
- case 'have-accounts':
- Log::debug('isJobConfigured returns false');
-
- return false;
- default:
- Log::debug('isJobConfigured returns true');
-
- return true;
- }
- }
-
- /**
- * @param ImportJob $job
- */
- public function setJob(ImportJob $job): void
- {
- // make repository
- $this->repository = app(ImportJobRepositoryInterface::class);
- $this->repository->setUser($job->user);
-
- // set default config:
- $defaultConfig = [
- 'has-token' => false,
- 'token' => '',
- 'token-expires' => 0,
- 'token-url' => '',
- 'is-redirected' => false,
- 'customer' => null,
- 'login' => null,
- 'stage' => 'initial',
- 'accounts' => '',
- 'accounts-mapped' => '',
- 'auto-start' => true,
- 'apply-rules' => true,
- ];
- $currentConfig = $this->repository->getConfiguration($job);
- $finalConfig = array_merge($defaultConfig, $currentConfig);
-
- // set default extended status:
- $extendedStatus = $this->repository->getExtendedStatus($job);
- $extendedStatus['steps'] = 6;
-
- // save to job:
- $job = $this->repository->setConfiguration($job, $finalConfig);
- $job = $this->repository->setExtendedStatus($job, $extendedStatus);
- $this->job = $job;
-
- }
-
- /**
- * Shorthand method.
- *
- * @return array
- */
- private function getConfig(): array
- {
- return $this->repository->getConfiguration($this->job);
- }
-}
diff --git a/app/Import/Converter/RabobankDebitCredit.php b/app/Import/Converter/RabobankDebitCredit.php
index 242f4ca38f..d426e52b5b 100644
--- a/app/Import/Converter/RabobankDebitCredit.php
+++ b/app/Import/Converter/RabobankDebitCredit.php
@@ -43,6 +43,12 @@ class RabobankDebitCredit implements ConverterInterface
return -1;
}
+ // old format:
+ if('A' === $value) {
+ Log::debug('Return -1');
+
+ return -1;
+ }
Log::debug('Return 1');
diff --git a/app/Import/FileProcessor/CsvProcessor.php b/app/Import/FileProcessor/CsvProcessor.php
deleted file mode 100644
index affd463daa..0000000000
--- a/app/Import/FileProcessor/CsvProcessor.php
+++ /dev/null
@@ -1,374 +0,0 @@
-.
- */
-declare(strict_types=1);
-
-namespace FireflyIII\Import\FileProcessor;
-
-use FireflyIII\Exceptions\FireflyException;
-use FireflyIII\Import\Object\ImportJournal;
-use FireflyIII\Import\Specifics\SpecificInterface;
-use FireflyIII\Models\ImportJob;
-use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
-use Illuminate\Support\Collection;
-use League\Csv\Reader;
-use League\Csv\Statement;
-use Log;
-
-/**
- * Class CsvProcessor, as the name suggests, goes over CSV file line by line and creates
- * "ImportJournal" objects, which are used in another step to create new journals and transactions
- * and what-not.
- */
-class CsvProcessor implements FileProcessorInterface
-{
- /** @var ImportJob */
- private $job;
- /** @var Collection */
- private $objects;
- /** @var ImportJobRepositoryInterface */
- private $repository;
- /** @var array */
- private $validConverters;
- /** @var array */
- private $validSpecifics;
-
- /**
- * FileProcessorInterface constructor.
- */
- public function __construct()
- {
- $this->objects = new Collection;
- $this->validSpecifics = array_keys(config('csv.import_specifics'));
- $this->validConverters = array_keys(config('csv.import_roles'));
- }
-
- /**
- * @return Collection
- *
- * @throws FireflyException
- */
- public function getObjects(): Collection
- {
- if (null === $this->job) {
- throw new FireflyException('Cannot call getObjects() without a job.');
- }
-
- return $this->objects;
- }
-
- /**
- * Does the actual job.
- *
- * @return bool
- *
- * @throws FireflyException
- * @throws \League\Csv\Exception
- */
- public function run(): bool
- {
- if (null === $this->job) {
- throw new FireflyException('Cannot call run() without a job.');
- }
- Log::debug('Now in CsvProcessor run(). Job is now running...');
-
- $entries = new Collection($this->getImportArray());
- $this->addStep();
- Log::notice('Building importable objects from CSV file.');
- Log::debug(sprintf('Number of entries: %d', $entries->count()));
- $notImported = $entries->filter(
- function (array $row, int $index) {
- $row = array_values($row);
- if ($this->rowAlreadyImported($row)) {
- $message = sprintf('Row #%d has already been imported.', $index);
- $this->repository->addError($this->job, $index, $message);
- Log::info($message);
-
- return null;
- }
-
- return $row;
- }
- );
- $this->addStep();
- Log::debug(sprintf('Number of entries left: %d', $notImported->count()));
-
- $notImported->each(
- function (array $row, int $index) {
- $journal = $this->importRow($index, $row);
- $this->objects->push($journal);
- }
- );
- $this->addStep();
-
- return true;
- }
-
- /**
- * Shorthand method to set the extended status.
- *
- * @codeCoverageIgnore
- *
- * @param array $array
- */
- public function setExtendedStatus(array $array): void
- {
- $this->repository->setExtendedStatus($this->job, $array);
- }
-
- /**
- * Set import job for this processor.
- *
- * @param ImportJob $job
- *
- * @return FileProcessorInterface
- */
- public function setJob(ImportJob $job): FileProcessorInterface
- {
- $this->job = $job;
- $this->repository = app(ImportJobRepositoryInterface::class);
- $this->repository->setUser($job->user);
-
- return $this;
- }
-
- /**
- * Shorthand method to add a step.
- *
- * @codeCoverageIgnore
- */
- private function addStep()
- {
- $this->repository->addStepsDone($this->job, 1);
- }
-
- /**
- * Add meta data to the individual value and verify that it can be handled in a later stage.
- *
- * @param int $index
- * @param string $value
- *
- * @return array
- *
- * @throws FireflyException
- */
- private function annotateValue(int $index, string $value)
- {
- $config = $this->getConfig();
- $role = $config['column-roles'][$index] ?? '_ignore';
- $mapped = $config['column-mapping-config'][$index][$value] ?? null;
-
- // throw error when not a valid converter.
- if (!\in_array($role, $this->validConverters)) {
- throw new FireflyException(sprintf('"%s" is not a valid role.', $role));
- }
-
- $entry = [
- 'role' => $role,
- 'value' => $value,
- 'mapped' => $mapped,
- ];
-
- return $entry;
- }
-
- /**
- * Shorthand method to return configuration.
- *
- * @codeCoverageIgnore
- *
- * @return array
- */
- private function getConfig(): array
- {
- return $this->repository->getConfiguration($this->job);
- }
-
- /**
- * @return array
- *
- * @throws \League\Csv\Exception
- * @throws \League\Csv\Exception
- */
- private function getImportArray(): array
- {
- $content = $this->repository->uploadFileContents($this->job);
- $config = $this->getConfig();
- $reader = Reader::createFromString($content);
- $delimiter = $config['delimiter'] ?? ',';
- $hasHeaders = $config['has-headers'] ?? false;
- $offset = 0;
- if ('tab' === $delimiter) {
- $delimiter = "\t"; // @codeCoverageIgnore
- }
- $reader->setDelimiter($delimiter);
- if ($hasHeaders) {
- $offset = 1;
- }
- $stmt = (new Statement)->offset($offset);
- $records = $stmt->process($reader);
- $return = [];
- foreach ($records as $record) {
- $return[] = $record;
- }
- Log::debug('Created a CSV reader.');
-
- return $return;
- }
-
- /**
- * Will return string representation of JSON error code.
- *
- * @param int $jsonError
- *
- * @codeCoverageIgnore
- *
- * @return string
- */
- private function getJsonError(int $jsonError): string
- {
- $messages = [
- JSON_ERROR_NONE => 'No JSON error',
- JSON_ERROR_DEPTH => 'The maximum stack depth has been exceeded.',
- JSON_ERROR_STATE_MISMATCH => 'Invalid or malformed JSON.',
- JSON_ERROR_CTRL_CHAR => 'Control character error, possibly incorrectly encoded.',
- JSON_ERROR_SYNTAX => 'Syntax error.',
- JSON_ERROR_UTF8 => 'Malformed UTF-8 characters, possibly incorrectly encoded.',
- JSON_ERROR_RECURSION => 'One or more recursive references in the value to be encoded.',
- JSON_ERROR_INF_OR_NAN => 'One or more NAN or INF values in the value to be encoded.',
- JSON_ERROR_UNSUPPORTED_TYPE => 'A value of a type that cannot be encoded was given.',
- JSON_ERROR_INVALID_PROPERTY_NAME => 'A property name that cannot be encoded was given.',
- JSON_ERROR_UTF16 => 'Malformed UTF-16 characters, possibly incorrectly encoded.',
- ];
- if (isset($messages[$jsonError])) {
- return $messages[$jsonError];
- }
-
- return 'Unknown JSON error';
- }
-
- /**
- * Hash an array and return the result.
- *
- * @param array $array
- *
- * @return string
- *
- * @throws FireflyException
- */
- private function getRowHash(array $array): string
- {
- $json = json_encode($array);
- $jsonError = json_last_error();
-
- if (false === $json) {
- throw new FireflyException(sprintf('Error while encoding JSON for CSV row: %s', $this->getJsonError($jsonError))); // @codeCoverageIgnore
- }
-
- return hash('sha256', $json);
- }
-
- /**
- * Take a row, build import journal by annotating each value and storing it in the import journal.
- *
- * @param int $index
- * @param array $row
- *
- * @return ImportJournal
- *
- * @throws FireflyException
- */
- private function importRow(int $index, array $row): ImportJournal
- {
- $row = array_values($row);
- Log::debug(sprintf('Now at row %d', $index));
- $row = $this->specifics($row);
- $hash = $this->getRowHash($row);
- $config = $this->getConfig();
-
- $journal = new ImportJournal;
- $journal->setUser($this->job->user);
- $journal->setHash($hash);
-
- /**
- * @var int
- * @var string $value
- */
- foreach ($row as $rowIndex => $value) {
- $value = trim((string)$value);
- if (\strlen($value) > 0) {
- $annotated = $this->annotateValue($rowIndex, $value);
- Log::debug('Annotated value', $annotated);
- $journal->setValue($annotated);
- }
- }
- // set some extra info:
- $importAccount = (int)($config['import-account'] ?? 0.0);
- $journal->asset->setDefaultAccountId($importAccount);
-
- return $journal;
- }
-
- /**
- * Checks if the row has not been imported before.
- *
- * @param array $array
- *
- * @return bool
- *
- * @throws FireflyException
- */
- private function rowAlreadyImported(array $array): bool
- {
- $hash = $this->getRowHash($array);
- $count = $this->repository->countByHash($hash);
- Log::debug(sprintf('Hash is %s and count is %d', $hash, $count));
-
- return $count > 0;
- }
-
- /**
- * And this is the point where the specifix go to work.
- *
- * @param array $row
- *
- * @return array
- *
- * @throws FireflyException
- */
- private function specifics(array $row): array
- {
- $config = $this->getConfig();
- $names = array_keys($config['specifics'] ?? []);
- foreach ($names as $name) {
- if (!\in_array($name, $this->validSpecifics)) {
- throw new FireflyException(sprintf('"%s" is not a valid class name', $name));
- }
-
- /** @var SpecificInterface $specific */
- $specific = app('FireflyIII\Import\Specifics\\' . $name);
-
- // it returns the row, possibly modified:
- $row = $specific->run($row);
- }
-
- return $row;
- }
-}
diff --git a/app/Import/JobConfiguration/BunqJobConfiguration.php b/app/Import/JobConfiguration/BunqJobConfiguration.php
new file mode 100644
index 0000000000..9ea6382b4d
--- /dev/null
+++ b/app/Import/JobConfiguration/BunqJobConfiguration.php
@@ -0,0 +1,129 @@
+.
+ */
+
+declare(strict_types=1);
+
+namespace FireflyIII\Import\JobConfiguration;
+
+use FireflyIII\Exceptions\FireflyException;
+use FireflyIII\Models\ImportJob;
+use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
+use FireflyIII\Support\Import\JobConfiguration\Bunq\BunqJobConfigurationInterface;
+use FireflyIII\Support\Import\JobConfiguration\Bunq\ChooseAccountsHandler;
+use FireflyIII\Support\Import\JobConfiguration\Bunq\NewBunqJobHandler;
+use Illuminate\Support\MessageBag;
+use Log;
+
+/**
+ * Class BunqJobConfiguration
+ */
+class BunqJobConfiguration implements JobConfigurationInterface
+{
+ /** @var BunqJobConfigurationInterface */
+ private $handler;
+ /** @var ImportJob */
+ private $importJob;
+ /** @var ImportJobRepositoryInterface */
+ private $repository;
+
+ /**
+ * Returns true when the initial configuration for this job is complete.
+ *
+ * @return bool
+ */
+ public function configurationComplete(): bool
+ {
+ return $this->handler->configurationComplete();
+ }
+
+ /**
+ * Store any data from the $data array into the job. Anything in the message bag will be flashed
+ * as an error to the user, regardless of its content.
+ *
+ * @param array $data
+ *
+ * @return MessageBag
+ */
+ public function configureJob(array $data): MessageBag
+ {
+ return $this->handler->configureJob($data);
+ }
+
+ /**
+ * Return the data required for the next step in the job configuration.
+ *
+ * @return array
+ */
+ public function getNextData(): array
+ {
+ return $this->handler->getNextData();
+ }
+
+ /**
+ * Returns the view of the next step in the job configuration.
+ *
+ * @return string
+ */
+ public function getNextView(): string
+ {
+ return $this->handler->getNextView();
+ }
+
+ /**
+ * @param ImportJob $importJob
+ *
+ * @throws FireflyException
+ */
+ public function setImportJob(ImportJob $importJob): void
+ {
+ $this->importJob = $importJob;
+ $this->repository = app(ImportJobRepositoryInterface::class);
+ $this->repository->setUser($importJob->user);
+ $this->handler = $this->getHandler();
+ }
+
+ /**
+ * @return BunqJobConfigurationInterface
+ * @throws FireflyException
+ */
+ private function getHandler(): BunqJobConfigurationInterface
+ {
+ Log::debug(sprintf('Now in BunqJobConfiguration::getHandler() with stage "%s"', $this->importJob->stage));
+ $handler = null;
+ switch ($this->importJob->stage) {
+ case 'new';
+ $handler = app(NewBunqJobHandler::class);
+ $handler->setImportJob($this->importJob);
+ break;
+ case 'choose-accounts':
+ /** @var ChooseAccountsHandler $handler */
+ $handler = app(ChooseAccountsHandler::class);
+ $handler->setImportJob($this->importJob);
+ break;
+ default:
+ // @codeCoverageIgnoreStart
+ throw new FireflyException(sprintf('Firefly III cannot create a configuration handler for stage "%s"', $this->importJob->stage));
+ // @codeCoverageIgnoreEnd
+ }
+
+ return $handler;
+ }
+}
\ No newline at end of file
diff --git a/app/Import/JobConfiguration/FakeJobConfiguration.php b/app/Import/JobConfiguration/FakeJobConfiguration.php
new file mode 100644
index 0000000000..81a96adfd7
--- /dev/null
+++ b/app/Import/JobConfiguration/FakeJobConfiguration.php
@@ -0,0 +1,159 @@
+.
+ */
+
+declare(strict_types=1);
+
+namespace FireflyIII\Import\JobConfiguration;
+
+use FireflyIII\Models\ImportJob;
+use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
+use Illuminate\Support\MessageBag;
+
+/**
+ * Class FakeJobConfiguration
+ */
+class FakeJobConfiguration implements JobConfigurationInterface
+{
+ /** @var ImportJob */
+ private $importJob;
+
+ /** @var ImportJobRepositoryInterface */
+ private $repository;
+
+ /**
+ * Returns true when the initial configuration for this job is complete.
+ *
+ * @return bool
+ */
+ public function configurationComplete(): bool
+ {
+ // configuration array of job must have two values:
+ // 'artist' must be 'david bowie', case insensitive
+ // 'song' must be 'golden years', case insensitive.
+ // if stage is not "new", then album must be 'station to station'
+ $config = $this->importJob->configuration;
+ if ($this->importJob->stage === 'new') {
+ return (isset($config['artist']) && 'david bowie' === strtolower($config['artist']))
+ && (isset($config['song']) && 'golden years' === strtolower($config['song']))
+ && isset($config['apply-rules']);
+ }
+
+ return isset($config['album']) && 'station to station' === strtolower($config['album']);
+
+
+ }
+
+ /**
+ * Store any data from the $data array into the job.
+ *
+ * @param array $data
+ *
+ * @return MessageBag
+ */
+ public function configureJob(array $data): MessageBag
+ {
+ $artist = strtolower($data['artist'] ?? '');
+ $song = strtolower($data['song'] ?? '');
+ $album = strtolower($data['album'] ?? '');
+ $applyRules = isset($data['apply_rules']) ? (int)$data['apply_rules'] === 1 : null;
+ $configuration = $this->importJob->configuration;
+ if ($artist === 'david bowie') {
+ // store artist
+ $configuration['artist'] = $artist;
+ }
+
+ if ($song === 'golden years') {
+ // store song
+ $configuration['song'] = $song;
+ }
+
+ if ($album === 'station to station') {
+ // store album
+ $configuration['album'] = $album;
+ }
+ if (null !== $applyRules) {
+ $configuration['apply-rules'] = $applyRules;
+ }
+
+ $this->repository->setConfiguration($this->importJob, $configuration);
+ $messages = new MessageBag();
+
+ if (\count($configuration) !== 3) {
+
+ $messages->add('some_key', 'Ignore this error: ' . \count($configuration));
+ }
+
+ return $messages;
+ }
+
+ /**
+ * Return the data required for the next step in the job configuration.
+ * @codeCoverageIgnore
+ * @return array
+ */
+ public function getNextData(): array
+ {
+ return [
+ 'rulesOptions' => [
+ 1 => trans('firefly.yes'),
+ 0 => trans('firefly.no'),
+ ],
+ ];
+ }
+
+ /**
+ * Returns the view of the next step in the job configuration.
+ *
+ * @return string
+ */
+ public function getNextView(): string
+ {
+ // first configure artist:
+ $config = $this->importJob->configuration;
+ $artist = $config['artist'] ?? '';
+ $song = $config['song'] ?? '';
+ $album = $config['album'] ?? '';
+ $applyRules = $config['apply-rules'] ?? null;
+ if (null === $applyRules) {
+ return 'import.fake.apply-rules';
+ }
+ if (strtolower($artist) !== 'david bowie') {
+ return 'import.fake.enter-artist';
+ }
+ if (strtolower($song) !== 'golden years') {
+ return 'import.fake.enter-song';
+ }
+ if (strtolower($album) !== 'station to station' && $this->importJob->stage !== 'new') {
+ return 'import.fake.enter-album';
+ }
+ return 'impossible-view'; // @codeCoverageIgnore
+ }
+
+ /**
+ * @param ImportJob $importJob
+ */
+ public function setImportJob(ImportJob $importJob): void
+ {
+ $this->importJob = $importJob;
+ $this->repository = app(ImportJobRepositoryInterface::class);
+ $this->repository->setUser($importJob->user);
+ }
+}
diff --git a/app/Import/JobConfiguration/FileJobConfiguration.php b/app/Import/JobConfiguration/FileJobConfiguration.php
new file mode 100644
index 0000000000..cfc1d18966
--- /dev/null
+++ b/app/Import/JobConfiguration/FileJobConfiguration.php
@@ -0,0 +1,157 @@
+.
+ */
+
+declare(strict_types=1);
+
+namespace FireflyIII\Import\JobConfiguration;
+
+
+use FireflyIII\Exceptions\FireflyException;
+use FireflyIII\Models\ImportJob;
+use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
+use FireflyIII\Support\Import\JobConfiguration\File\FileConfigurationInterface;
+use FireflyIII\Support\Import\JobConfiguration\File\ConfigureMappingHandler;
+use FireflyIII\Support\Import\JobConfiguration\File\ConfigureRolesHandler;
+use FireflyIII\Support\Import\JobConfiguration\File\ConfigureUploadHandler;
+use FireflyIII\Support\Import\JobConfiguration\File\NewFileJobHandler;
+use Illuminate\Support\MessageBag;
+
+/**
+ * Class FileJobConfiguration
+ */
+class FileJobConfiguration implements JobConfigurationInterface
+{
+ /** @var ImportJob */
+ private $importJob;
+ /** @var ImportJobRepositoryInterface */
+ private $repository;
+
+ /**
+ * Returns true when the initial configuration for this job is complete.
+ *
+ * @return bool
+ */
+ public function configurationComplete(): bool
+ {
+ return $this->importJob->stage === 'ready_to_run';
+ }
+
+ /**
+ * Store any data from the $data array into the job. Anything in the message bag will be flashed
+ * as an error to the user, regardless of its content.
+ *
+ * @param array $data
+ *
+ * @return MessageBag
+ * @throws FireflyException
+ */
+ public function configureJob(array $data): MessageBag
+ {
+ $configurator = $this->getConfigurationObject();
+ $configurator->setImportJob($this->importJob);
+
+ return $configurator->configureJob($data);
+ }
+
+ /**
+ * Return the data required for the next step in the job configuration.
+ *
+ * @throws FireflyException
+ * @return array
+ */
+ public function getNextData(): array
+ {
+ $configurator = $this->getConfigurationObject();
+ $configurator->setImportJob($this->importJob);
+
+ return $configurator->getNextData();
+ }
+
+ /**
+ * Returns the view of the next step in the job configuration.
+ *
+ * @throws FireflyException
+ * @return string
+ */
+ public function getNextView(): string
+ {
+ switch ($this->importJob->stage) {
+ case 'new':
+ return 'import.file.new';
+ case 'configure-upload':
+ return 'import.file.configure-upload';
+ break;
+ case 'roles':
+ return 'import.file.roles';
+ break;
+ case 'map':
+ return 'import.file.map';
+ break;
+ default:
+ // @codeCoverageIgnoreStart
+ throw new FireflyException(
+ sprintf('FileJobConfiguration::getNextView() cannot handle stage "%s"', $this->importJob->stage)
+ );
+ // @codeCoverageIgnoreEnd
+ }
+ }
+
+ /**
+ * @param ImportJob $importJob
+ */
+ public function setImportJob(ImportJob $importJob): void
+ {
+ $this->importJob = $importJob;
+ $this->repository = app(ImportJobRepositoryInterface::class);
+ $this->repository->setUser($importJob->user);
+ }
+
+ /**
+ * Get the configuration handler for this specific stage.
+ *
+ * @return FileConfigurationInterface
+ * @throws FireflyException
+ */
+ private function getConfigurationObject(): FileConfigurationInterface
+ {
+ $class = 'DoNotExist';
+ switch ($this->importJob->stage) {
+ case 'new': // has nothing, no file upload or anything.
+ $class = NewFileJobHandler::class;
+ break;
+ case 'configure-upload':
+ $class = ConfigureUploadHandler::class;
+ break;
+ case 'roles':
+ $class = ConfigureRolesHandler::class;
+ break;
+ case 'map':
+ $class = ConfigureMappingHandler::class;
+ break;
+ }
+ if (!class_exists($class)) {
+ throw new FireflyException(sprintf('Class %s does not exist in getConfigurationClass().', $class)); // @codeCoverageIgnore
+ }
+
+ return app($class);
+ }
+}
diff --git a/app/Import/JobConfiguration/JobConfigurationInterface.php b/app/Import/JobConfiguration/JobConfigurationInterface.php
new file mode 100644
index 0000000000..0560240b17
--- /dev/null
+++ b/app/Import/JobConfiguration/JobConfigurationInterface.php
@@ -0,0 +1,68 @@
+.
+ */
+declare(strict_types=1);
+
+namespace FireflyIII\Import\JobConfiguration;
+
+use FireflyIII\Models\ImportJob;
+use Illuminate\Support\MessageBag;
+
+/**
+ * Interface JobConfigurationInterface.
+ */
+interface JobConfigurationInterface
+{
+ /**
+ * Returns true when the initial configuration for this job is complete.
+ *
+ * @return bool
+ */
+ public function configurationComplete(): bool;
+
+ /**
+ * Store any data from the $data array into the job. Anything in the message bag will be flashed
+ * as an error to the user, regardless of its content.
+ *
+ * @param array $data
+ *
+ * @return MessageBag
+ */
+ public function configureJob(array $data): MessageBag;
+
+ /**
+ * Return the data required for the next step in the job configuration.
+ *
+ * @return array
+ */
+ public function getNextData(): array;
+
+ /**
+ * Returns the view of the next step in the job configuration.
+ *
+ * @return string
+ */
+ public function getNextView(): string;
+
+ /**
+ * @param ImportJob $importJob
+ */
+ public function setImportJob(ImportJob $importJob): void;
+}
diff --git a/app/Import/JobConfiguration/SpectreJobConfiguration.php b/app/Import/JobConfiguration/SpectreJobConfiguration.php
new file mode 100644
index 0000000000..1251ebf6f4
--- /dev/null
+++ b/app/Import/JobConfiguration/SpectreJobConfiguration.php
@@ -0,0 +1,152 @@
+.
+ */
+
+declare(strict_types=1);
+
+namespace FireflyIII\Import\JobConfiguration;
+
+use FireflyIII\Exceptions\FireflyException;
+use FireflyIII\Models\ImportJob;
+use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
+use FireflyIII\Support\Import\JobConfiguration\Spectre\AuthenticatedConfigHandler;
+use FireflyIII\Support\Import\JobConfiguration\Spectre\AuthenticatedHandler;
+use FireflyIII\Support\Import\JobConfiguration\Spectre\AuthenticateHandler;
+use FireflyIII\Support\Import\JobConfiguration\Spectre\ChooseAccount;
+use FireflyIII\Support\Import\JobConfiguration\Spectre\ChooseAccountsHandler;
+use FireflyIII\Support\Import\JobConfiguration\Spectre\ChooseLoginHandler;
+use FireflyIII\Support\Import\JobConfiguration\Spectre\DoAuthenticateHandler;
+use FireflyIII\Support\Import\JobConfiguration\Spectre\NewConfig;
+use FireflyIII\Support\Import\JobConfiguration\Spectre\NewSpectreJobHandler;
+use FireflyIII\Support\Import\JobConfiguration\Spectre\SpectreJobConfigurationInterface;
+use Illuminate\Support\MessageBag;
+use Log;
+
+/**
+ * Class SpectreJobConfiguration
+ */
+class SpectreJobConfiguration implements JobConfigurationInterface
+{
+ /** @var SpectreJobConfigurationInterface */
+ private $handler;
+ /** @var ImportJob */
+ private $importJob;
+ /** @var ImportJobRepositoryInterface */
+ private $repository;
+
+ /**
+ * Returns true when the initial configuration for this job is complete.
+ *
+ * @return bool
+ */
+ public function configurationComplete(): bool
+ {
+ return $this->handler->configurationComplete();
+ }
+
+ /**
+ * Store any data from the $data array into the job. Anything in the message bag will be flashed
+ * as an error to the user, regardless of its content.
+ *
+ * @param array $data
+ *
+ * @return MessageBag
+ */
+ public function configureJob(array $data): MessageBag
+ {
+ return $this->handler->configureJob($data);
+ }
+
+ /**
+ * Return the data required for the next step in the job configuration.
+ *
+ * @return array
+ */
+ public function getNextData(): array
+ {
+ return $this->handler->getNextData();
+ }
+
+ /**
+ * Returns the view of the next step in the job configuration.
+ *
+ * @return string
+ */
+ public function getNextView(): string
+ {
+ return $this->handler->getNextView();
+ }
+
+ /**
+ * @param ImportJob $importJob
+ *
+ * @throws FireflyException
+ */
+ public function setImportJob(ImportJob $importJob): void
+ {
+ $this->importJob = $importJob;
+ $this->repository = app(ImportJobRepositoryInterface::class);
+ $this->repository->setUser($importJob->user);
+ $this->handler = $this->getHandler();
+ }
+
+ /**
+ * @return SpectreJobConfigurationInterface
+ * @throws FireflyException
+ */
+ private function getHandler(): SpectreJobConfigurationInterface
+ {
+ Log::debug(sprintf('Now in SpectreJobConfiguration::getHandler() with stage "%s"', $this->importJob->stage));
+ $handler = null;
+ switch ($this->importJob->stage) {
+ case 'new':
+ /** @var NewSpectreJobHandler $handler */
+ $handler = app(NewSpectreJobHandler::class);
+ $handler->setImportJob($this->importJob);
+ break;
+ case 'do-authenticate':
+ /** @var DoAuthenticateHandler $handler */
+ $handler = app(DoAuthenticateHandler::class);
+ $handler->setImportJob($this->importJob);
+ break;
+ case 'choose-login':
+ /** @var ChooseLoginHandler $handler */
+ $handler = app(ChooseLoginHandler::class);
+ $handler->setImportJob($this->importJob);
+ break;
+ case 'authenticated':
+ /** @var AuthenticatedHandler $handler */
+ $handler = app(AuthenticatedHandler::class);
+ $handler->setImportJob($this->importJob);
+ break;
+ case 'choose-accounts':
+ /** @var ChooseAccountsHandler $handler */
+ $handler = app(ChooseAccountsHandler::class);
+ $handler->setImportJob($this->importJob);
+ break;
+ default:
+ // @codeCoverageIgnoreStart
+ throw new FireflyException(sprintf('Firefly III cannot create a configuration handler for stage "%s"', $this->importJob->stage));
+ // @codeCoverageIgnoreEnd
+ }
+
+ return $handler;
+ }
+}
\ No newline at end of file
diff --git a/app/Import/Logging/CommandHandler.php b/app/Import/Logging/CommandHandler.php
deleted file mode 100644
index c1dfc85773..0000000000
--- a/app/Import/Logging/CommandHandler.php
+++ /dev/null
@@ -1,71 +0,0 @@
-.
- */
-declare(strict_types=1);
-
-namespace FireflyIII\Import\Logging;
-
-use Illuminate\Console\Command;
-use Monolog\Handler\AbstractProcessingHandler;
-
-/**
- * @codeCoverageIgnore
- * Class CommandHandler.
- */
-class CommandHandler extends AbstractProcessingHandler
-{
- /** @var Command */
- private $command;
-
- /**
- * Handler constructor.
- *
- * @param Command $command
- */
- public function __construct(Command $command)
- {
- parent::__construct();
- $this->command = $command;
-
- $this->changeLevel(env('APP_LOG_LEVEL', 'info'));
- }
-
- /**
- * Writes the record down to the log of the implementing handler.
- *
- * @param array $record
- */
- protected function write(array $record)
- {
- $this->command->line(trim($record['formatted']));
- }
-
- /**
- * @param string $level
- */
- private function changeLevel(string $level)
- {
- $level = strtoupper($level);
- $reference = sprintf('\Monolog\Logger::%s', $level);
- if (\defined($reference)) {
- $this->setLevel(\constant($reference));
- }
- }
-}
diff --git a/app/Import/Mapper/Bills.php b/app/Import/Mapper/Bills.php
index 6457affe4f..8caa0f76a3 100644
--- a/app/Import/Mapper/Bills.php
+++ b/app/Import/Mapper/Bills.php
@@ -43,7 +43,7 @@ class Bills implements MapperInterface
/** @var Bill $bill */
foreach ($result as $bill) {
$billId = (int)$bill->id;
- $list[$billId] = $bill->name . ' [' . $bill->match . ']';
+ $list[$billId] = $bill->name;
}
asort($list);
$list = [0 => trans('import.map_do_not_map')] + $list;
diff --git a/app/Import/Object/ImportAccount.php b/app/Import/Object/ImportAccount.php
index fe2ffc8767..fdfef58293 100644
--- a/app/Import/Object/ImportAccount.php
+++ b/app/Import/Object/ImportAccount.php
@@ -30,6 +30,8 @@ use FireflyIII\User;
use Log;
/**
+ * @deprecated
+ * @codeCoverageIgnore
* Class ImportAccount.
*/
class ImportAccount
diff --git a/app/Import/Object/ImportBill.php b/app/Import/Object/ImportBill.php
index 19364f9df6..5222334aa6 100644
--- a/app/Import/Object/ImportBill.php
+++ b/app/Import/Object/ImportBill.php
@@ -29,6 +29,8 @@ use Log;
use Steam;
/**
+ * @deprecated
+ * @codeCoverageIgnore
* Class ImportBill.
*/
class ImportBill
diff --git a/app/Import/Object/ImportBudget.php b/app/Import/Object/ImportBudget.php
index 53e92a8f80..55f4e6e559 100644
--- a/app/Import/Object/ImportBudget.php
+++ b/app/Import/Object/ImportBudget.php
@@ -28,6 +28,8 @@ use FireflyIII\User;
use Log;
/**
+ * @deprecated
+ * @codeCoverageIgnore
* Class ImportBudget.
*/
class ImportBudget
diff --git a/app/Import/Object/ImportCategory.php b/app/Import/Object/ImportCategory.php
index 9427d74871..bcdf0a9477 100644
--- a/app/Import/Object/ImportCategory.php
+++ b/app/Import/Object/ImportCategory.php
@@ -28,6 +28,8 @@ use FireflyIII\User;
use Log;
/**
+ * @deprecated
+ * @codeCoverageIgnore
* Class ImportCategory
*/
class ImportCategory
diff --git a/app/Import/Object/ImportCurrency.php b/app/Import/Object/ImportCurrency.php
index 2d63bf9955..b570632064 100644
--- a/app/Import/Object/ImportCurrency.php
+++ b/app/Import/Object/ImportCurrency.php
@@ -28,6 +28,8 @@ use FireflyIII\User;
use Log;
/**
+ * @deprecated
+ * @codeCoverageIgnore
* Class ImportCurrency
*/
class ImportCurrency
diff --git a/app/Import/Object/ImportJournal.php b/app/Import/Object/ImportJournal.php
index 9fe1d82349..c4e96db676 100644
--- a/app/Import/Object/ImportJournal.php
+++ b/app/Import/Object/ImportJournal.php
@@ -33,6 +33,8 @@ use Log;
use Steam;
/**
+ * @deprecated
+ * @codeCoverageIgnore
* Class ImportJournal.
*/
class ImportJournal
@@ -158,6 +160,14 @@ class ImportJournal
return $this->description;
}
+ /**
+ * @return string
+ */
+ public function getExternalId(): string
+ {
+ return $this->externalId;
+ }
+
/**
* @return string|null
*/
@@ -231,7 +241,6 @@ class ImportJournal
return null;
}
-
/**
* @param string $hash
*/
diff --git a/app/Import/Prerequisites/BunqPrerequisites.php b/app/Import/Prerequisites/BunqPrerequisites.php
index 286268b919..ea39453f3a 100644
--- a/app/Import/Prerequisites/BunqPrerequisites.php
+++ b/app/Import/Prerequisites/BunqPrerequisites.php
@@ -22,12 +22,14 @@ declare(strict_types=1);
namespace FireflyIII\Import\Prerequisites;
+use bunq\Exception\BunqException;
+use bunq\Util\BunqEnumApiEnvironmentType;
+use FireflyIII\Exceptions\FireflyException;
+use FireflyIII\Services\Bunq\ApiContext;
use FireflyIII\Services\IP\IPRetrievalInterface;
use FireflyIII\User;
-use Illuminate\Http\Request;
use Illuminate\Support\MessageBag;
use Log;
-use Preferences;
/**
* This class contains all the routines necessary to connect to Bunq.
@@ -38,14 +40,13 @@ class BunqPrerequisites implements PrerequisitesInterface
private $user;
/**
- * Returns view name that allows user to fill in prerequisites. Currently asks for the API key.
+ * @codeCoverageIgnore
+ * Returns view name that allows user to fill in prerequisites.
*
* @return string
*/
public function getView(): string
{
- Log::debug('Now in BunqPrerequisites::getView()');
-
return 'import.bunq.prerequisites';
}
@@ -57,105 +58,155 @@ class BunqPrerequisites implements PrerequisitesInterface
public function getViewParameters(): array
{
Log::debug('Now in BunqPrerequisites::getViewParameters()');
- $key = '';
- $serverIP = '';
+ $key = '';
+ $externalIP = '';
if ($this->hasApiKey()) {
- $key = Preferences::getForUser($this->user, 'bunq_api_key', null)->data;
+ $key = app('preferences')->getForUser($this->user, 'bunq_api_key', null)->data;
}
- if ($this->hasServerIP()) {
- $serverIP = Preferences::getForUser($this->user, 'external_ip', null)->data;
+ if ($this->hasExternalIP()) {
+ $externalIP = app('preferences')->getForUser($this->user, 'bunq_external_ip', null)->data;
}
- if (!$this->hasServerIP()) {
+ if (!$this->hasExternalIP()) {
/** @var IPRetrievalInterface $service */
- $service = app(IPRetrievalInterface::class);
- $serverIP = (string)$service->getIP();
+ $service = app(IPRetrievalInterface::class);
+ $externalIP = (string)$service->getIP();
}
-
- // get IP address
- return ['key' => $key, 'ip' => $serverIP];
+ return ['api_key' => $key, 'external_ip' => $externalIP];
}
/**
- * Returns if this import method has any special prerequisites such as config
- * variables or other things. The only thing we verify is the presence of the API key. Everything else
- * tumbles into place: no installation token? Will be requested. No device server? Will be created. Etc.
+ * Indicate if all prerequisites have been met.
*
* @return bool
*/
- public function hasPrerequisites(): bool
+ public function isComplete(): bool
{
- $hasApiKey = $this->hasApiKey();
- $hasServerIP = $this->hasServerIP();
-
- return !$hasApiKey || !$hasServerIP;
+ return $this->hasApiKey() && $this->hasExternalIP() && $this->hasApiContext();
}
/**
+ * @codeCoverageIgnore
* Set the user for this Prerequisites-routine. Class is expected to implement and save this.
*
* @param User $user
*/
public function setUser(User $user): void
{
- Log::debug(sprintf('Now in setUser(#%d)', $user->id));
$this->user = $user;
}
/**
- * This method responds to the user's submission of an API key. It tries to register this instance as a new Firefly III device.
- * If this fails, the error is returned in a message bag and the user is notified (this is fairly friendly).
+ * This method responds to the user's submission of an API key. Should do nothing but store the value.
*
- * @param Request $request
+ * Errors must be returned in the message bag under the field name they are requested by.
+ *
+ * @param array $data
*
* @return MessageBag
*/
- public function storePrerequisites(Request $request): MessageBag
+ public function storePrerequisites(array $data): MessageBag
{
- $apiKey = $request->get('api_key');
- $serverIP = $request->get('external_ip');
+ $apiKey = $data['api_key'] ?? '';
+ $externalIP = $data['external_ip'] ?? '';
Log::debug('Storing bunq API key');
- Preferences::setForUser($this->user, 'bunq_api_key', $apiKey);
- Preferences::setForUser($this->user, 'external_ip', $serverIP);
+ app('preferences')->setForUser($this->user, 'bunq_api_key', $apiKey);
+ app('preferences')->setForUser($this->user, 'bunq_external_ip', $externalIP);
+
+ $environment = $this->getBunqEnvironment();
+ $deviceDescription = 'Firefly III v' . config('firefly.version');
+ $permittedIps = [$externalIP];
+
+ try {
+ /** @var ApiContext $object */
+ $object = app(ApiContext::class);
+ $apiContext = $object->create($environment, $apiKey, $deviceDescription, $permittedIps);
+ } catch (FireflyException $e) {
+ $messages = new MessageBag();
+ $messages->add('bunq_error', $e->getMessage());
+
+ return $messages;
+ }
+ // store context in JSON:
+ try {
+ $json = $apiContext->toJson();
+ // @codeCoverageIgnoreStart
+ } catch (BunqException $e) {
+ $messages = new MessageBag();
+ $messages->add('bunq_error', $e->getMessage());
+
+ return $messages;
+ }
+ // @codeCoverageIgnoreEnd
+
+ // and store for user:
+ app('preferences')->setForUser($this->user, 'bunq_api_context', $json);
return new MessageBag;
}
+ /**
+ * @codeCoverageIgnore
+ * @return BunqEnumApiEnvironmentType
+ */
+ private function getBunqEnvironment(): BunqEnumApiEnvironmentType
+ {
+ $env = env('BUNQ_USE_SANDBOX');
+ if (null === $env) {
+ return BunqEnumApiEnvironmentType::PRODUCTION();
+ }
+ if (false === $env) {
+ return BunqEnumApiEnvironmentType::PRODUCTION();
+ }
+
+ return BunqEnumApiEnvironmentType::SANDBOX();
+ }
+
+ /**
+ * @return bool
+ */
+ private function hasApiContext(): bool
+ {
+ $apiContext = app('preferences')->getForUser($this->user, 'bunq_api_context', null);
+ if (null === $apiContext) {
+ return false;
+ }
+ if ('' === (string)$apiContext->data) {
+ return false;
+ }
+
+ return true;
+ }
+
/**
* @return bool
*/
private function hasApiKey(): bool
{
- $apiKey = Preferences::getForUser($this->user, 'bunq_api_key', false);
+ $apiKey = app('preferences')->getForUser($this->user, 'bunq_api_key', null);
if (null === $apiKey) {
return false;
}
- if (null === $apiKey->data) {
+ if ('' === (string)$apiKey->data) {
return false;
}
- if (\strlen((string)$apiKey->data) === 64) {
- return true;
- }
- return false;
+ return true;
}
/**
* @return bool
*/
- private function hasServerIP(): bool
+ private function hasExternalIP(): bool
{
- $serverIP = Preferences::getForUser($this->user, 'external_ip', false);
- if (null === $serverIP) {
+ $externalIP = app('preferences')->getForUser($this->user, 'bunq_external_ip', null);
+ if (null === $externalIP) {
return false;
}
- if (null === $serverIP->data) {
+ if ('' === (string)$externalIP->data) {
return false;
}
- if (\strlen((string)$serverIP->data) > 6) {
- return true;
- }
- return false;
+ return true;
}
}
diff --git a/app/Import/Prerequisites/FakePrerequisites.php b/app/Import/Prerequisites/FakePrerequisites.php
new file mode 100644
index 0000000000..ac8c07affb
--- /dev/null
+++ b/app/Import/Prerequisites/FakePrerequisites.php
@@ -0,0 +1,128 @@
+.
+ */
+declare(strict_types=1);
+
+namespace FireflyIII\Import\Prerequisites;
+
+use FireflyIII\User;
+use Illuminate\Http\Request;
+use Illuminate\Support\MessageBag;
+
+/**
+ * This class contains all the routines necessary for the fake import provider.
+ *
+ * Class FakePrerequisites
+ */
+class FakePrerequisites implements PrerequisitesInterface
+{
+ /** @var User */
+ private $user;
+
+ /**
+ * Returns view name that allows user to fill in prerequisites. Currently asks for the API key.
+ *
+ * @codeCoverageIgnore
+ * @return string
+ */
+ public function getView(): string
+ {
+ return 'import.fake.prerequisites';
+ }
+
+ /**
+ * Returns any values required for the prerequisites-view.
+ *
+ * @return array
+ */
+ public function getViewParameters(): array
+ {
+ $apiKey = '';
+ if ($this->hasApiKey()) {
+ $apiKey = app('preferences')->getForUser($this->user, 'fake_api_key', null)->data;
+ }
+ $oldKey = (string)\request()->old('api_key');
+ if ($oldKey !== '') {
+ $apiKey = \request()->old('api_key'); // @codeCoverageIgnore
+ }
+
+ return ['api_key' => $apiKey];
+ }
+
+ /**
+ * Indicate if all prerequisites have been met.
+ *
+ * @return bool
+ */
+ public function isComplete(): bool
+ {
+ return $this->hasApiKey();
+ }
+
+ /**
+ * Set the user for this Prerequisites-routine. Class is expected to implement and save this.
+ *
+ * @param User $user
+ */
+ public function setUser(User $user): void
+ {
+ $this->user = $user;
+
+ }
+
+ /**
+ * @param array $data
+ *
+ * @return MessageBag
+ */
+ public function storePrerequisites(array $data): MessageBag
+ {
+ $apiKey = $data['api_key'] ?? '';
+ $messageBag = new MessageBag();
+ if (32 !== \strlen($apiKey)) {
+ $messageBag->add('api_key', 'API key must be 32 chars.');
+
+ return $messageBag;
+ }
+
+ app('preferences')->setForUser($this->user, 'fake_api_key', $apiKey);
+
+ return $messageBag;
+ }
+
+ /**
+ * @return bool
+ */
+ private function hasApiKey(): bool
+ {
+ $apiKey = app('preferences')->getForUser($this->user, 'fake_api_key', false);
+ if (null === $apiKey) {
+ return false;
+ }
+ if (null === $apiKey->data) {
+ return false;
+ }
+ if (\strlen((string)$apiKey->data) === 32) {
+ return true;
+ }
+
+ return false;
+ }
+}
diff --git a/app/Import/Prerequisites/FilePrerequisites.php b/app/Import/Prerequisites/FilePrerequisites.php
index e2177af913..c9200489e3 100644
--- a/app/Import/Prerequisites/FilePrerequisites.php
+++ b/app/Import/Prerequisites/FilePrerequisites.php
@@ -22,21 +22,18 @@ declare(strict_types=1);
namespace FireflyIII\Import\Prerequisites;
-use FireflyIII\Exceptions\FireflyException;
use FireflyIII\User;
-use Illuminate\Http\Request;
use Illuminate\Support\MessageBag;
/**
+ * @codeCoverageIgnore
+ *
* This class contains all the routines necessary to import from a file. Hint: there are none.
*/
class FilePrerequisites implements PrerequisitesInterface
{
- /** @var User */
- private $user;
-
/**
- * Returns view name that allows user to fill in prerequisites. Currently asks for the API key.
+ * Returns view name that allows user to fill in prerequisites.
*
* @return string
*/
@@ -56,23 +53,13 @@ class FilePrerequisites implements PrerequisitesInterface
}
/**
- * Returns if this import method has any special prerequisites such as config
- * variables or other things. The only thing we verify is the presence of the API key. Everything else
- * tumbles into place: no installation token? Will be requested. No device server? Will be created. Etc.
- *
- * True if prerequisites. False if not.
+ * Indicate if all prerequisites have been met.
*
* @return bool
- *
- * @throws FireflyException
*/
- public function hasPrerequisites(): bool
+ public function isComplete(): bool
{
- if ($this->user->hasRole('demo')) {
- throw new FireflyException('Apologies, the demo user cannot import files.');
- }
-
- return false;
+ return true;
}
/**
@@ -82,19 +69,19 @@ class FilePrerequisites implements PrerequisitesInterface
*/
public function setUser(User $user): void
{
- $this->user = $user;
}
/**
- * This method responds to the user's submission of an API key. It tries to register this instance as a new Firefly III device.
- * If this fails, the error is returned in a message bag and the user is notified (this is fairly friendly).
+ * This method responds to the user's submission of an API key. Should do nothing but store the value.
*
- * @param Request $request
+ * Errors must be returned in the message bag under the field name they are requested by.
+ *
+ * @param array $data
*
* @return MessageBag
*/
- public function storePrerequisites(Request $request): MessageBag
+ public function storePrerequisites(array $data): MessageBag
{
return new MessageBag;
}
diff --git a/app/Import/Prerequisites/PrerequisitesInterface.php b/app/Import/Prerequisites/PrerequisitesInterface.php
index 699ea43b31..588821eeca 100644
--- a/app/Import/Prerequisites/PrerequisitesInterface.php
+++ b/app/Import/Prerequisites/PrerequisitesInterface.php
@@ -46,12 +46,11 @@ interface PrerequisitesInterface
public function getViewParameters(): array;
/**
- * Returns if this import method has any special prerequisites such as config
- * variables or other things.
+ * Indicate if all prerequisites have been met.
*
* @return bool
*/
- public function hasPrerequisites(): bool;
+ public function isComplete(): bool;
/**
* Set the user for this Prerequisites-routine. Class is expected to implement and save this.
@@ -61,9 +60,13 @@ interface PrerequisitesInterface
public function setUser(User $user): void;
/**
- * @param Request $request
+ * This method responds to the user's submission of an API key. Should do nothing but store the value.
+ *
+ * Errors must be returned in the message bag under the field name they are requested by.
+ *
+ * @param array $data
*
* @return MessageBag
*/
- public function storePrerequisites(Request $request): MessageBag;
+ public function storePrerequisites(array $data): MessageBag;
}
diff --git a/app/Import/Prerequisites/SpectrePrerequisites.php b/app/Import/Prerequisites/SpectrePrerequisites.php
index a780c3ddd1..239e3f274b 100644
--- a/app/Import/Prerequisites/SpectrePrerequisites.php
+++ b/app/Import/Prerequisites/SpectrePrerequisites.php
@@ -24,10 +24,8 @@ namespace FireflyIII\Import\Prerequisites;
use FireflyIII\Models\Preference;
use FireflyIII\User;
-use Illuminate\Http\Request;
use Illuminate\Support\MessageBag;
use Log;
-use Preferences;
/**
* This class contains all the routines necessary to connect to Spectre.
@@ -38,7 +36,7 @@ class SpectrePrerequisites implements PrerequisitesInterface
private $user;
/**
- * Returns view name that allows user to fill in prerequisites. Currently asks for the API key.
+ * Returns view name that allows user to fill in prerequisites.
*
* @return string
*/
@@ -54,37 +52,29 @@ class SpectrePrerequisites implements PrerequisitesInterface
*/
public function getViewParameters(): array
{
- $publicKey = $this->getPublicKey();
- $subTitle = (string)trans('import.spectre_title');
- $subTitleIcon = 'fa-archive';
+ /** @var Preference $appIdPreference */
+ $appIdPreference = app('preferences')->getForUser($this->user, 'spectre_app_id', null);
+ $appId = null === $appIdPreference ? '' : $appIdPreference->data;
+ /** @var Preference $secretPreference */
+ $secretPreference = app('preferences')->getForUser($this->user, 'spectre_secret', null);
+ $secret = null === $secretPreference ? '' : $secretPreference->data;
+ $publicKey = $this->getPublicKey();
- return compact('publicKey', 'subTitle', 'subTitleIcon');
+ return [
+ 'app_id' => $appId,
+ 'secret' => $secret,
+ 'public_key' => $publicKey,
+ ];
}
/**
- * Returns if this import method has any special prerequisites such as config
- * variables or other things. The only thing we verify is the presence of the API key. Everything else
- * tumbles into place: no installation token? Will be requested. No device server? Will be created. Etc.
+ * Indicate if all prerequisites have been met.
*
* @return bool
*/
- public function hasPrerequisites(): bool
+ public function isComplete(): bool
{
- $values = [
- Preferences::getForUser($this->user, 'spectre_app_id', false),
- Preferences::getForUser($this->user, 'spectre_secret', false),
- ];
- /** @var Preference $value */
- foreach ($values as $value) {
- if (false === $value->data || null === $value->data) {
- Log::info(sprintf('Config var "%s" is missing.', $value->name));
-
- return true;
- }
- }
- Log::debug('All prerequisites are here!');
-
- return false;
+ return $this->hasAppId() && $this->hasSecret();
}
/**
@@ -95,22 +85,22 @@ class SpectrePrerequisites implements PrerequisitesInterface
public function setUser(User $user): void
{
$this->user = $user;
-
}
/**
- * This method responds to the user's submission of an API key. It tries to register this instance as a new Firefly III device.
- * If this fails, the error is returned in a message bag and the user is notified (this is fairly friendly).
+ * This method responds to the user's submission of an API key. Should do nothing but store the value.
*
- * @param Request $request
+ * Errors must be returned in the message bag under the field name they are requested by.
+ *
+ * @param array $data
*
* @return MessageBag
*/
- public function storePrerequisites(Request $request): MessageBag
+ public function storePrerequisites(array $data): MessageBag
{
Log::debug('Storing Spectre API keys..');
- Preferences::setForUser($this->user, 'spectre_app_id', $request->get('app_id'));
- Preferences::setForUser($this->user, 'spectre_secret', $request->get('secret'));
+ app('preferences')->setForUser($this->user, 'spectre_app_id', $data['app_id'] ?? null);
+ app('preferences')->setForUser($this->user, 'spectre_secret', $data['secret'] ?? null);
Log::debug('Done!');
return new MessageBag;
@@ -139,8 +129,8 @@ class SpectrePrerequisites implements PrerequisitesInterface
// Extract the public key from $res to $pubKey
$pubKey = openssl_pkey_get_details($res);
- Preferences::setForUser($this->user, 'spectre_private_key', $privKey);
- Preferences::setForUser($this->user, 'spectre_public_key', $pubKey['key']);
+ app('preferences')->setForUser($this->user, 'spectre_private_key', $privKey);
+ app('preferences')->setForUser($this->user, 'spectre_public_key', $pubKey['key']);
Log::debug('Created key pair');
}
@@ -153,15 +143,47 @@ class SpectrePrerequisites implements PrerequisitesInterface
private function getPublicKey(): string
{
Log::debug('get public key');
- $preference = Preferences::getForUser($this->user, 'spectre_public_key', null);
+ $preference = app('preferences')->getForUser($this->user, 'spectre_public_key', null);
if (null === $preference) {
Log::debug('public key is null');
// create key pair
$this->createKeyPair();
}
- $preference = Preferences::getForUser($this->user, 'spectre_public_key', null);
+ $preference = app('preferences')->getForUser($this->user, 'spectre_public_key', null);
Log::debug('Return public key for user');
return $preference->data;
}
+
+ /**
+ * @return bool
+ */
+ private function hasAppId(): bool
+ {
+ $appId = app('preferences')->getForUser($this->user, 'spectre_app_id', null);
+ if (null === $appId) {
+ return false;
+ }
+ if ('' === (string)$appId->data) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * @return bool
+ */
+ private function hasSecret(): bool
+ {
+ $secret = app('preferences')->getForUser($this->user, 'spectre_secret', null);
+ if (null === $secret) {
+ return false;
+ }
+ if ('' === (string)$secret->data) {
+ return false;
+ }
+
+ return true;
+ }
}
diff --git a/app/Import/Routine/BunqRoutine.php b/app/Import/Routine/BunqRoutine.php
index 98156f9d7e..0f29d089f8 100644
--- a/app/Import/Routine/BunqRoutine.php
+++ b/app/Import/Routine/BunqRoutine.php
@@ -23,892 +23,83 @@ declare(strict_types=1);
namespace FireflyIII\Import\Routine;
-use Carbon\Carbon;
-use DB;
use FireflyIII\Exceptions\FireflyException;
-use FireflyIII\Factory\AccountFactory;
-use FireflyIII\Factory\TransactionJournalFactory;
-use FireflyIII\Models\Account;
-use FireflyIII\Models\AccountType;
use FireflyIII\Models\ImportJob;
-use FireflyIII\Models\TransactionJournalMeta;
-use FireflyIII\Models\TransactionType;
-use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
-use FireflyIII\Repositories\Tag\TagRepositoryInterface;
-use FireflyIII\Services\Bunq\Id\DeviceServerId;
-use FireflyIII\Services\Bunq\Object\DeviceServer;
-use FireflyIII\Services\Bunq\Object\LabelMonetaryAccount;
-use FireflyIII\Services\Bunq\Object\MonetaryAccountBank;
-use FireflyIII\Services\Bunq\Object\Payment;
-use FireflyIII\Services\Bunq\Object\ServerPublicKey;
-use FireflyIII\Services\Bunq\Object\UserCompany;
-use FireflyIII\Services\Bunq\Object\UserPerson;
-use FireflyIII\Services\Bunq\Request\DeviceServerRequest;
-use FireflyIII\Services\Bunq\Request\DeviceSessionRequest;
-use FireflyIII\Services\Bunq\Request\InstallationTokenRequest;
-use FireflyIII\Services\Bunq\Request\ListDeviceServerRequest;
-use FireflyIII\Services\Bunq\Request\ListMonetaryAccountRequest;
-use FireflyIII\Services\Bunq\Request\ListPaymentRequest;
-use FireflyIII\Services\Bunq\Token\InstallationToken;
-use FireflyIII\Services\Bunq\Token\SessionToken;
-use FireflyIII\Services\IP\IPRetrievalInterface;
-use Illuminate\Support\Collection;
+use FireflyIII\Support\Import\Routine\Bunq\StageImportDataHandler;
+use FireflyIII\Support\Import\Routine\Bunq\StageNewHandler;
use Log;
-use Preferences;
/**
* Class BunqRoutine
- *
- * Steps before import:
- * 1) register device complete.
- *
- * Stage: 'initial'.
- *
- * 1) Get an installation token (if not present)
- * 2) Register device (if not found)
- *
- * Stage 'registered'
- *
- * 1) Get a session token. (new session)
- * 2) store user person / user company
- *
- * Stage 'logged-in'
- *
- * Get list of bank accounts
- *
- * Stage 'have-accounts'
- *
- * Map accounts to existing accounts
- *
- * Stage 'do-import'?
*/
class BunqRoutine implements RoutineInterface
{
- /** @var Collection */
- public $errors;
- /** @var Collection */
- public $journals;
- /** @var int */
- public $lines = 0;
- /** @var AccountFactory */
- private $accountFactory;
- /** @var AccountRepositoryInterface */
- private $accountRepository;
/** @var ImportJob */
- private $job;
- /** @var TransactionJournalFactory */
- private $journalFactory;
+ private $importJob;
+
/** @var ImportJobRepositoryInterface */
private $repository;
/**
- * ImportRoutine constructor.
- */
- public function __construct()
- {
- $this->journals = new Collection;
- $this->errors = new Collection;
- }
-
- /**
- * @return Collection
- */
- public function getErrors(): Collection
- {
- return $this->errors;
- }
-
- /**
- * @return Collection
- */
- public function getJournals(): Collection
- {
- return $this->journals;
- }
-
- /**
- * @return int
- */
- public function getLines(): int
- {
- return $this->lines;
- }
-
- /**
- * @return bool
+ * At the end of each run(), the import routine must set the job to the expected status.
+ *
+ * The final status of the routine must be "provider_finished".
*
* @throws FireflyException
*/
- public function run(): bool
+ public function run(): void
{
- Log::info(sprintf('Start with import job %s using Bunq.', $this->job->key));
- set_time_limit(0);
- // this method continues with the job and is called by whenever a stage is
- // finished
- $this->continueJob();
+ Log::debug(sprintf('Now in SpectreRoutine::run() with status "%s" and stage "%s".', $this->importJob->status, $this->importJob->stage));
+ $valid = ['ready_to_run']; // should be only ready_to_run
+ if (\in_array($this->importJob->status, $valid, true)) {
+ switch ($this->importJob->stage) {
+ default:
+ throw new FireflyException(sprintf('SpectreRoutine cannot handle stage "%s".', $this->importJob->stage)); // @codeCoverageIgnore
+ case 'new':
+ // list all of the users accounts.
+ $this->repository->setStatus($this->importJob, 'running');
+ /** @var StageNewHandler $handler */
+ $handler = app(StageNewHandler::class);
+ $handler->setImportJob($this->importJob);
+ $handler->run();
- return true;
- }
+ // make user choose accounts to import from.
+ $this->repository->setStage($this->importJob, 'choose-accounts');
+ $this->repository->setStatus($this->importJob, 'need_job_config');
- /**
- * @param ImportJob $job
- */
- public function setJob(ImportJob $job)
- {
- $this->job = $job;
- $this->repository = app(ImportJobRepositoryInterface::class);
- $this->accountRepository = app(AccountRepositoryInterface::class);
- $this->accountFactory = app(AccountFactory::class);
- $this->journalFactory = app(TransactionJournalFactory::class);
- $this->repository->setUser($job->user);
- $this->accountRepository->setUser($job->user);
- $this->accountFactory->setUser($job->user);
- $this->journalFactory->setUser($job->user);
- }
+ return;
+ case 'go-for-import':
+ // list all of the users accounts.
+ $this->repository->setStatus($this->importJob, 'running');
- /**
- * @throws FireflyException
- */
- protected function continueJob()
- {
- // if in "configuring"
- if ('configuring' === $this->getStatus()) {
- Log::debug('Job is in configuring stage, will do nothing.');
+ /** @var StageImportDataHandler $handler */
+ $handler = app(StageImportDataHandler::class);
+ $handler->setImportJob($this->importJob);
+ $handler->run();
+ $transactions = $handler->getTransactions();
- return;
- }
- $stage = $this->getConfig()['stage'] ?? 'unknown';
- Log::debug(sprintf('Now in continueJob() for stage %s', $stage));
- switch ($stage) {
- case 'initial':
- // register device and get tokens.
- $this->runStageInitial();
- $this->continueJob();
- break;
- case 'registered':
- // get all bank accounts of user.
- $this->runStageRegistered();
- $this->continueJob();
- break;
- case 'logged-in':
- $this->runStageLoggedIn();
- break;
- case 'have-accounts':
- // do nothing in this stage. Job should revert to config routine.
- break;
- case 'have-account-mapping':
- $this->setStatus('running');
- $this->runStageHaveAccountMapping();
+ $this->repository->setTransactions($this->importJob, $transactions);
+ $this->repository->setStatus($this->importJob, 'provider_finished');
+ $this->repository->setStage($this->importJob, 'final');
- break;
- default:
- throw new FireflyException(sprintf('No action for stage %s!', $stage));
- break;
- }
- }
-
- /**
- * @throws FireflyException
- */
- protected function runStageInitial(): void
- {
- $this->addStep();
- Log::debug('In runStageInitial()');
- $this->setStatus('running');
-
- // register the device at Bunq:
- $serverId = $this->registerDevice();
- Log::debug(sprintf('Found device server with id %d', $serverId->getId()));
-
- $config = $this->getConfig();
- $config['stage'] = 'registered';
- $this->setConfig($config);
- $this->addStep();
- }
-
- /**
- * Get a session token + userperson + usercompany. Store it in the job.
- *
- * @throws FireflyException
- */
- protected function runStageRegistered(): void
- {
- $this->addStep();
- Log::debug('Now in runStageRegistered()');
- $apiKey = (string)Preferences::getForUser($this->job->user, 'bunq_api_key')->data;
- $serverPublicKey = new ServerPublicKey(Preferences::getForUser($this->job->user, 'bunq_server_public_key', [])->data);
- $installationToken = $this->getInstallationToken();
- $request = new DeviceSessionRequest;
- $request->setInstallationToken($installationToken);
- $request->setPrivateKey($this->getPrivateKey());
- $request->setServerPublicKey($serverPublicKey);
- $request->setSecret($apiKey);
- $request->call();
- $this->addStep();
-
- Log::debug('Requested new session.');
-
- $deviceSession = $request->getDeviceSessionId();
- $userPerson = $request->getUserPerson();
- $userCompany = $request->getUserCompany();
- $sessionToken = $request->getSessionToken();
-
- $config = $this->getConfig();
- $config['device_session_id'] = $deviceSession->toArray();
- $config['user_person'] = $userPerson->toArray();
- $config['user_company'] = $userCompany->toArray();
- $config['session_token'] = $sessionToken->toArray();
- $config['stage'] = 'logged-in';
- $this->setConfig($config);
- $this->addStep();
-
- Log::debug('Session stored in job.');
- }
-
- /**
- * Shorthand method.
- */
- private function addStep(): void
- {
- $this->addSteps(1);
- }
-
- /**
- * Shorthand method.
- *
- * @param int $count
- */
- private function addSteps(int $count): void
- {
- $this->repository->addStepsDone($this->job, $count);
- }
-
- /**
- * Shorthand method
- *
- * @param int $steps
- */
- private function addTotalSteps(int $steps): void
- {
- $this->repository->addTotalSteps($this->job, $steps);
- }
-
- /**
- * @param int $paymentId
- *
- * @return bool
- */
- private function alreadyImported(int $paymentId): bool
- {
- $count = TransactionJournalMeta::where('name', 'bunq_payment_id')
- ->where('data', json_encode($paymentId))->count();
-
- Log::debug(sprintf('Transaction #%d is %d time(s) in the database.', $paymentId, $count));
-
- return $count > 0;
- }
-
- /**
- * @param LabelMonetaryAccount $party
- * @param string $expectedType
- *
- * @return Account
- */
- private function convertToAccount(LabelMonetaryAccount $party, string $expectedType): Account
- {
- Log::debug('in convertToAccount()');
-
- if ($party->getIban() !== null) {
- // find opposing party by IBAN first.
- $result = $this->accountRepository->findByIbanNull($party->getIban(), [$expectedType]);
- if (null !== $result) {
- Log::debug(sprintf('Search for %s resulted in account %s (#%d)', $party->getIban(), $result->name, $result->id));
-
- return $result;
- }
-
- // try to find asset account just in case:
- if ($expectedType !== AccountType::ASSET) {
- $result = $this->accountRepository->findByIbanNull($party->getIban(), [AccountType::ASSET]);
- if (null !== $result) {
- Log::debug(sprintf('Search for Asset "%s" resulted in account %s (#%d)', $party->getIban(), $result->name, $result->id));
-
- return $result;
- }
+ return;
}
}
-
- // create new account:
- $data = [
- 'user_id' => $this->job->user_id,
- 'iban' => $party->getIban(),
- 'name' => $party->getLabelUser()->getDisplayName(),
- 'account_type_id' => null,
- 'accountType' => $expectedType,
- 'virtualBalance' => null,
- 'active' => true,
-
- ];
- $account = $this->accountFactory->create($data);
- Log::debug(
- sprintf(
- 'Converted label monetary account %s to %s account %s (#%d)',
- $party->getLabelUser()->getDisplayName(),
- $expectedType,
- $account->name, $account->id
- )
- );
-
- return $account;
+ throw new FireflyException(sprintf('bunq import routine cannot handle status "%s"', $this->importJob->status)); // @codeCoverageIgnore
}
+
/**
- * This method creates a new public/private keypair for the user. This isn't really secure, since the key is generated on the fly with
- * no regards for HSM's, smart cards or other things. It would require some low level programming to get this right. But the private key
- * is stored encrypted in the database so it's something.
+ * @param ImportJob $importJob
+ *
+ * @return void
*/
- private function createKeyPair(): void
+ public function setImportJob(ImportJob $importJob): void
{
- Log::debug('Now in createKeyPair()');
- $private = Preferences::getForUser($this->job->user, 'bunq_private_key', null);
- $public = Preferences::getForUser($this->job->user, 'bunq_public_key', null);
-
- if (!(null === $private && null === $public)) {
- Log::info('Already have public and private key, return NULL.');
-
- return;
- }
-
- Log::debug('Generate new key pair for user.');
- $keyConfig = [
- 'digest_alg' => 'sha512',
- 'private_key_bits' => 2048,
- 'private_key_type' => OPENSSL_KEYTYPE_RSA,
- ];
- // Create the private and public key
- $res = openssl_pkey_new($keyConfig);
-
- // Extract the private key from $res to $privKey
- $privKey = '';
- openssl_pkey_export($res, $privKey);
-
- // Extract the public key from $res to $pubKey
- $pubKey = openssl_pkey_get_details($res);
-
- Preferences::setForUser($this->job->user, 'bunq_private_key', $privKey);
- Preferences::setForUser($this->job->user, 'bunq_public_key', $pubKey['key']);
- Log::debug('Created and stored key pair');
+ $this->importJob = $importJob;
+ $this->repository = app(ImportJobRepositoryInterface::class);
+ $this->repository->setUser($importJob->user);
}
- /**
- * Shorthand method.
- *
- * @return array
- */
- private function getConfig(): array
- {
- return $this->repository->getConfiguration($this->job);
- }
-
- /**
- * Try to detect the current device ID (in case this instance has been registered already.
- *
- * @return DeviceServerId
- *
- * @throws FireflyException
- */
- private function getExistingDevice(): ?DeviceServerId
- {
- Log::debug('Now in getExistingDevice()');
- $installationToken = $this->getInstallationToken();
- $serverPublicKey = $this->getServerPublicKey();
- $request = new ListDeviceServerRequest;
- $remoteIp = $this->getRemoteIp();
- $request->setInstallationToken($installationToken);
- $request->setServerPublicKey($serverPublicKey);
- $request->setPrivateKey($this->getPrivateKey());
- $request->call();
- $devices = $request->getDevices();
- /** @var DeviceServer $device */
- foreach ($devices as $device) {
- if ($device->getIp() === $remoteIp) {
- Log::debug(sprintf('This instance is registered as device #%s', $device->getId()->getId()));
-
- return $device->getId();
- }
- }
- Log::info('This instance is not yet registered.');
-
- return null;
- }
-
- /**
- * Shorthand method.
- *
- * @return array
- */
- private function getExtendedStatus(): array
- {
- return $this->repository->getExtendedStatus($this->job);
- }
-
- /**
- * Get the installation token, either from the users preferences or from Bunq.
- *
- * @return InstallationToken
- *
- * @throws FireflyException
- */
- private function getInstallationToken(): InstallationToken
- {
- Log::debug('Now in getInstallationToken().');
- $token = Preferences::getForUser($this->job->user, 'bunq_installation_token', null);
- if (null !== $token) {
- Log::debug('Have installation token, return it.');
-
- return new InstallationToken($token->data);
- }
- Log::debug('Have no installation token, request one.');
-
- // verify bunq api code:
- $publicKey = $this->getPublicKey();
- $request = new InstallationTokenRequest;
- $request->setPublicKey($publicKey);
- $request->call();
- Log::debug('Sent request for installation token.');
-
- $installationToken = $request->getInstallationToken();
- $installationId = $request->getInstallationId();
- $serverPublicKey = $request->getServerPublicKey();
-
- Log::debug('Have all values from InstallationTokenRequest');
-
-
- Preferences::setForUser($this->job->user, 'bunq_installation_token', $installationToken->toArray());
- Preferences::setForUser($this->job->user, 'bunq_installation_id', $installationId->toArray());
- Preferences::setForUser($this->job->user, 'bunq_server_public_key', $serverPublicKey->toArray());
-
- Log::debug('Stored token, ID and pub key.');
-
- return $installationToken;
- }
-
- /**
- * Get the private key from the users preferences.
- *
- * @return string
- */
- private function getPrivateKey(): string
- {
- Log::debug('In getPrivateKey()');
- $preference = Preferences::getForUser($this->job->user, 'bunq_private_key', null);
- if (null === $preference) {
- Log::debug('private key is null');
- // create key pair
- $this->createKeyPair();
- }
- $preference = Preferences::getForUser($this->job->user, 'bunq_private_key', null);
- Log::debug('Return private key for user');
-
- return (string)$preference->data;
- }
-
- /**
- * Get a public key from the users preferences.
- *
- * @return string
- */
- private function getPublicKey(): string
- {
- Log::debug('Now in getPublicKey()');
- $preference = Preferences::getForUser($this->job->user, 'bunq_public_key', null);
- if (null === $preference) {
- Log::debug('public key is NULL.');
- // create key pair
- $this->createKeyPair();
- }
- $preference = Preferences::getForUser($this->job->user, 'bunq_public_key', null);
- Log::debug('Return public key for user');
-
- return (string)$preference->data;
- }
-
- /**
- * Request users server remote IP. Let's assume this value will not change any time soon.
- *
- * @return string
- *
- */
- private function getRemoteIp(): ?string
- {
-
- $preference = Preferences::getForUser($this->job->user, 'external_ip', null);
- if (null === $preference) {
-
- /** @var IPRetrievalInterface $service */
- $service = app(IPRetrievalInterface::class);
- $serverIp = $service->getIP();
- if (null !== $serverIp) {
- Preferences::setForUser($this->job->user, 'external_ip', $serverIp);
- }
-
- return $serverIp;
- }
-
- return $preference->data;
- }
-
- /**
- * Get the public key of the server, necessary to verify server signature.
- *
- * @return ServerPublicKey
- *
- * @throws FireflyException
- */
- private function getServerPublicKey(): ServerPublicKey
- {
- $pref = Preferences::getForUser($this->job->user, 'bunq_server_public_key', null)->data;
- if (null === $pref) {
- throw new FireflyException('Cannot determine bunq server public key, but should have it at this point.');
- }
-
- return new ServerPublicKey($pref);
- }
-
- /**
- * Shorthand method.
- *
- * @return string
- */
- private function getStatus(): string
- {
- return $this->repository->getStatus($this->job);
- }
-
- /**
- * Import the transactions that were found.
- *
- * @param array $payments
- *
- * @throws FireflyException
- */
- private function importPayments(array $payments): void
- {
- Log::debug('Going to run importPayments()');
- $journals = new Collection;
- $config = $this->getConfig();
- foreach ($payments as $accountId => $data) {
- Log::debug(sprintf('Now running for bunq account #%d with %d payment(s).', $accountId, \count($data['payments'])));
- /** @var Payment $payment */
- foreach ($data['payments'] as $index => $payment) {
- Log::debug(sprintf('Now at payment #%d with ID #%d', $index, $payment->getId()));
- // store or find counter party:
- $counterParty = $payment->getCounterParty();
- $amount = $payment->getAmount();
- $paymentId = $payment->getId();
- if ($this->alreadyImported($paymentId)) {
- Log::error(sprintf('Already imported bunq payment with id #%d', $paymentId));
-
- // add three steps to keep up
- $this->addSteps(3);
- continue;
- }
- Log::debug(sprintf('Amount is %s %s', $amount->getCurrency(), $amount->getValue()));
- $expected = AccountType::EXPENSE;
- if (bccomp($amount->getValue(), '0') === 1) {
- // amount + means that its a deposit.
- $expected = AccountType::REVENUE;
- Log::debug('Will make opposing account revenue.');
- }
- $opposing = $this->convertToAccount($counterParty, $expected);
- $account = $this->accountRepository->findNull($config['accounts-mapped'][$accountId]);
- $type = TransactionType::WITHDRAWAL;
-
- $this->addStep();
-
- Log::debug(sprintf('Will store withdrawal between "%s" (%d) and "%s" (%d)', $account->name, $account->id, $opposing->name, $opposing->id));
-
- // start storing stuff:
- $source = $account;
- $destination = $opposing;
- if (bccomp($amount->getValue(), '0') === 1) {
- // its a deposit:
- $source = $opposing;
- $destination = $account;
- $type = TransactionType::DEPOSIT;
- Log::debug('Will make it a deposit.');
- }
- if ($account->accountType->type === AccountType::ASSET && $opposing->accountType->type === AccountType::ASSET) {
- $type = TransactionType::TRANSFER;
- Log::debug('Both are assets, will make transfer.');
- }
-
- $storeData = [
- 'user' => $this->job->user_id,
- 'type' => $type,
- 'date' => $payment->getCreated(),
- 'description' => $payment->getDescription(),
- 'piggy_bank_id' => null,
- 'piggy_bank_name' => null,
- 'bill_id' => null,
- 'bill_name' => null,
- 'tags' => [$payment->getType(), $payment->getSubType()],
- 'internal_reference' => $payment->getId(),
- 'notes' => null,
- 'bunq_payment_id' => $payment->getId(),
- 'transactions' => [
- // single transaction:
- [
- 'description' => null,
- 'amount' => $amount->getValue(),
- 'currency_id' => null,
- 'currency_code' => $amount->getCurrency(),
- 'foreign_amount' => null,
- 'foreign_currency_id' => null,
- 'foreign_currency_code' => null,
- 'budget_id' => null,
- 'budget_name' => null,
- 'category_id' => null,
- 'category_name' => null,
- 'source_id' => $source->id,
- 'source_name' => null,
- 'destination_id' => $destination->id,
- 'destination_name' => null,
- 'reconciled' => false,
- 'identifier' => 0,
- ],
- ],
- ];
- $journal = $this->journalFactory->create($storeData);
- Log::debug(sprintf('Stored journal with ID #%d', $journal->id));
- $this->addStep();
- $journals->push($journal);
-
- }
- }
- if ($journals->count() > 0) {
- // link to tag
- /** @var TagRepositoryInterface $repository */
- $repository = app(TagRepositoryInterface::class);
- $repository->setUser($this->job->user);
- $data = [
- 'tag' => trans('import.import_with_key', ['key' => $this->job->key]),
- 'date' => new Carbon,
- 'description' => null,
- 'latitude' => null,
- 'longitude' => null,
- 'zoomLevel' => null,
- 'tagMode' => 'nothing',
- ];
- $tag = $repository->store($data);
- $extended = $this->getExtendedStatus();
- $extended['tag'] = $tag->id;
- $this->setExtendedStatus($extended);
-
- Log::debug(sprintf('Created tag #%d ("%s")', $tag->id, $tag->tag));
- Log::debug('Looping journals...');
- $tagId = $tag->id;
-
- foreach ($journals as $journal) {
- Log::debug(sprintf('Linking journal #%d to tag #%d...', $journal->id, $tagId));
- DB::table('tag_transaction_journal')->insert(['transaction_journal_id' => $journal->id, 'tag_id' => $tagId]);
- $this->addStep();
- }
- Log::info(sprintf('Linked %d journals to tag #%d ("%s")', $journals->count(), $tag->id, $tag->tag));
- }
-
- // set status to "finished"?
- // update job:
- $this->setStatus('finished');
- }
-
- /**
- * To install Firefly III as a new device:
- * - Send an installation token request.
- * - Use this token to send a device server request
- * - Store the installation token
- * - Use the installation token each time we need a session.
- *
- * @throws FireflyException
- */
- private function registerDevice(): DeviceServerId
- {
- Log::debug('Now in registerDevice()');
- $deviceServerId = Preferences::getForUser($this->job->user, 'bunq_device_server_id', null);
- $serverIp = $this->getRemoteIp();
- if (null !== $deviceServerId) {
- Log::debug('Already have device server ID.');
-
- return new DeviceServerId($deviceServerId->data);
- }
-
- Log::debug('Device server ID is null, we have to find an existing one or register a new one.');
- $installationToken = $this->getInstallationToken();
- $serverPublicKey = $this->getServerPublicKey();
- $apiKey = Preferences::getForUser($this->job->user, 'bunq_api_key', '');
- $this->addStep();
-
- // try get the current from a list:
- $deviceServerId = $this->getExistingDevice();
- $this->addStep();
- if (null !== $deviceServerId) {
- Log::debug('Found device server ID in existing devices list.');
-
- return $deviceServerId;
- }
-
- Log::debug('Going to create new DeviceServerRequest() because nothing found in existing list.');
- $request = new DeviceServerRequest;
- $request->setPrivateKey($this->getPrivateKey());
- $request->setDescription('Firefly III v' . config('firefly.version') . ' for ' . $this->job->user->email);
- $request->setSecret($apiKey->data);
- $request->setPermittedIps([$serverIp]);
- $request->setInstallationToken($installationToken);
- $request->setServerPublicKey($serverPublicKey);
- $deviceServerId = null;
- // try to register device:
- try {
- $request->call();
- $deviceServerId = $request->getDeviceServerId();
- } catch (FireflyException $e) {
- Log::error($e->getMessage());
- // we really have to quit at this point :(
- throw new FireflyException($e->getMessage());
- }
- if (null === $deviceServerId) {
- throw new FireflyException('Was not able to register server with bunq. Please see the log files.');
- }
-
- Preferences::setForUser($this->job->user, 'bunq_device_server_id', $deviceServerId->toArray());
- Log::debug(sprintf('Server ID: %s', json_encode($deviceServerId)));
-
- return $deviceServerId;
- }
-
- /**
- * Will download the transactions for each account that is selected to be imported from.
- * Will of course also update the number of steps and what-not.
- *
- * @throws FireflyException
- */
- private function runStageHaveAccountMapping(): void
- {
- $config = $this->getConfig();
- $user = new UserPerson($config['user_person']);
- $mapping = $config['accounts-mapped'];
- $token = new SessionToken($config['session_token']);
- $count = 0;
- $all = [];
- if (0 === $user->getId()) {
- $user = new UserCompany($config['user_company']);
- Log::debug(sprintf('Will try to get transactions for company #%d', $user->getId()));
- }
-
- $this->addTotalSteps(\count($config['accounts']) * 2);
-
- foreach ($config['accounts'] as $accountData) {
- $this->addStep();
- $account = new MonetaryAccountBank($accountData);
- $importId = $account->getId();
- if (isset($mapping[$importId])) {
- Log::debug(sprintf('Will grab payments for account %s', $account->getDescription()));
- $request = new ListPaymentRequest();
- $request->setPrivateKey($this->getPrivateKey());
- $request->setServerPublicKey($this->getServerPublicKey());
- $request->setSessionToken($token);
- $request->setUserId($user->getId());
- $request->setAccount($account);
- $request->call();
- $payments = $request->getPayments();
-
- // store in array
- $all[$account->getId()] = [
- 'account' => $account,
- 'import_id' => $importId,
- 'payments' => $payments,
- ];
- $count += \count($payments);
- }
- Log::debug(sprintf('Total number of payments: %d', $count));
- $this->addStep();
- // add steps for import:
- $this->addTotalSteps($count * 3);
- $this->importPayments($all);
- }
-
- // update job to be complete, I think?
- }
-
- /**
- * @throws FireflyException
- */
- private function runStageLoggedIn(): void
- {
- $this->addStep();
- // grab new session token:
- $config = $this->getConfig();
- $token = new SessionToken($config['session_token']);
- $user = new UserPerson($config['user_person']);
- if (0 === $user->getId()) {
- $user = new UserCompany($config['user_company']);
- }
-
- // list accounts request
- $request = new ListMonetaryAccountRequest();
- $request->setServerPublicKey($this->getServerPublicKey());
- $request->setPrivateKey($this->getPrivateKey());
- $request->setUserId($user->getId());
- $request->setSessionToken($token);
- $request->call();
- $accounts = $request->getMonetaryAccounts();
- $arr = [];
- Log::debug(sprintf('Get monetary accounts, found %d accounts.', $accounts->count()));
- $this->addStep();
-
- /** @var MonetaryAccountBank $account */
- foreach ($accounts as $account) {
- $arr[] = $account->toArray();
- }
-
- $config = $this->getConfig();
- $config['accounts'] = $arr;
- $config['stage'] = 'have-accounts';
- $this->setConfig($config);
-
- // once the accounts are stored, go to configuring stage:
- // update job, set status to "configuring".
- $this->setStatus('configuring');
- $this->addStep();
- }
-
- /**
- * Shorthand.
- *
- * @param array $config
- */
- private function setConfig(array $config): void
- {
- $this->repository->setConfiguration($this->job, $config);
- }
-
- /**
- * Shorthand method.
- *
- * @param array $extended
- */
- private function setExtendedStatus(array $extended): void
- {
- $this->repository->setExtendedStatus($this->job, $extended);
- }
-
- /**
- * Shorthand.
- *
- * @param string $status
- */
- private function setStatus(string $status): void
- {
- $this->repository->setStatus($this->job, $status);
- }
}
diff --git a/app/Import/Routine/FakeRoutine.php b/app/Import/Routine/FakeRoutine.php
new file mode 100644
index 0000000000..bd609706c5
--- /dev/null
+++ b/app/Import/Routine/FakeRoutine.php
@@ -0,0 +1,106 @@
+.
+ */
+
+declare(strict_types=1);
+
+namespace FireflyIII\Import\Routine;
+
+use FireflyIII\Exceptions\FireflyException;
+use FireflyIII\Models\ImportJob;
+use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
+use FireflyIII\Support\Import\Routine\Fake\StageAhoyHandler;
+use FireflyIII\Support\Import\Routine\Fake\StageFinalHandler;
+use FireflyIII\Support\Import\Routine\Fake\StageNewHandler;
+use Log;
+
+/**
+ * Class FakeRoutine
+ */
+class FakeRoutine implements RoutineInterface
+{
+ /** @var ImportJob */
+ private $importJob;
+ /** @var ImportJobRepositoryInterface */
+ private $repository;
+
+ /**
+ * Fake import routine has three stages:
+ *
+ * "new": will quietly log gibberish for 15 seconds, then switch to stage "ahoy".
+ * will also set status to "ready_to_run" so it will arrive here again.
+ * "ahoy": will log some nonsense and then drop job into status:"need_job_config" to force it back to the job config routine.
+ * "final": will do some logging, sleep for 10 seconds and then finish. Generates 5 random transactions.
+ *
+ * @return void
+ * @throws FireflyException
+ */
+ public function run(): void
+ {
+ Log::debug(sprintf('Now in run() for fake routine with status: %s', $this->importJob->status));
+ if ($this->importJob->status !== 'ready_to_run') {
+ throw new FireflyException(sprintf('Fake job should have status "ready_to_run", not "%s"', $this->importJob->status)); // @codeCoverageIgnore
+ }
+
+ switch ($this->importJob->stage) {
+ default:
+ throw new FireflyException(sprintf('Fake routine cannot handle stage "%s".', $this->importJob->stage)); // @codeCoverageIgnore
+ case 'new':
+ $this->repository->setStatus($this->importJob, 'running');
+ /** @var StageNewHandler $handler */
+ $handler = app(StageNewHandler::class);
+ $handler->run();
+ $this->repository->setStage($this->importJob, 'ahoy');
+ // set job finished this step:
+ $this->repository->setStatus($this->importJob, 'ready_to_run');
+
+ return;
+ case 'ahoy':
+ $this->repository->setStatus($this->importJob, 'running');
+ /** @var StageAhoyHandler $handler */
+ $handler = app(StageAhoyHandler::class);
+ $handler->run();
+ $this->repository->setStatus($this->importJob, 'need_job_config');
+ $this->repository->setStage($this->importJob, 'final');
+ break;
+ case 'final':
+ $this->repository->setStatus($this->importJob, 'running');
+ /** @var StageFinalHandler $handler */
+ $handler = app(StageFinalHandler::class);
+ $handler->setImportJob($this->importJob);
+ $transactions = $handler->getTransactions();
+ $this->repository->setStatus($this->importJob, 'provider_finished');
+ $this->repository->setStage($this->importJob, 'final');
+ $this->repository->setTransactions($this->importJob, $transactions);
+ }
+ }
+
+ /**
+ * @param ImportJob $importJob
+ *
+ * @return
+ */
+ public function setImportJob(ImportJob $importJob): void
+ {
+ $this->importJob = $importJob;
+ $this->repository = app(ImportJobRepositoryInterface::class);
+ $this->repository->setUser($importJob->user);
+ }
+}
diff --git a/app/Import/Routine/FileRoutine.php b/app/Import/Routine/FileRoutine.php
index b4c58bc856..db228ac494 100644
--- a/app/Import/Routine/FileRoutine.php
+++ b/app/Import/Routine/FileRoutine.php
@@ -22,15 +22,10 @@ declare(strict_types=1);
namespace FireflyIII\Import\Routine;
-use Carbon\Carbon;
-use DB;
-use FireflyIII\Import\FileProcessor\FileProcessorInterface;
-use FireflyIII\Import\Storage\ImportStorage;
+use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\ImportJob;
-use FireflyIII\Models\Tag;
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
-use FireflyIII\Repositories\Tag\TagRepositoryInterface;
-use Illuminate\Support\Collection;
+use FireflyIII\Support\Import\Routine\File\FileProcessorInterface;
use Log;
/**
@@ -38,271 +33,62 @@ use Log;
*/
class FileRoutine implements RoutineInterface
{
- /** @var Collection */
- public $errors;
- /** @var Collection */
- public $journals;
- /** @var int */
- public $lines = 0;
/** @var ImportJob */
- private $job;
-
+ private $importJob;
/** @var ImportJobRepositoryInterface */
private $repository;
/**
- * ImportRoutine constructor.
- */
- public function __construct()
- {
- $this->journals = new Collection;
- $this->errors = new Collection;
- }
-
- /**
- * @return Collection
- */
- public function getErrors(): Collection
- {
- return $this->errors;
- }
-
- /**
- * @return Collection
- */
- public function getJournals(): Collection
- {
- return $this->journals;
- }
-
- /**
- * @return int
- */
- public function getLines(): int
- {
- return $this->lines;
- }
-
- /**
+ * At the end of each run(), the import routine must set the job to the expected status.
*
+ * The final status of the routine must be "provider_finished".
+ *
+ * @throws FireflyException
*/
- public function run(): bool
+ public function run(): void
{
- if ('configured' !== $this->getStatus()) {
- Log::error(sprintf('Job %s is in state "%s" so it cannot be started.', $this->job->key, $this->getStatus()));
+ Log::debug(sprintf('Now in run() for file routine with status: %s', $this->importJob->status));
+ if ($this->importJob->status === 'ready_to_run') {
+ $this->repository->setStatus($this->importJob, 'running');
+ // get processor, depending on file type
+ // is just CSV for now.
+ $processor = $this->getProcessor();
+ $processor->setImportJob($this->importJob);
+ $transactions = $processor->run();
- return false;
+ $this->repository->setStatus($this->importJob, 'provider_finished');
+ $this->repository->setStage($this->importJob, 'final');
+ $this->repository->setTransactions($this->importJob, $transactions);
+
+ return;
}
- set_time_limit(0);
- Log::info(sprintf('Start with import job %s', $this->job->key));
-
- // total steps: 6
- $this->setTotalSteps(6);
-
- $importObjects = $this->getImportObjects();
- $this->lines = $importObjects->count();
- $this->addStep();
-
- // total steps can now be extended. File has been scanned. 7 steps per line:
- $this->addTotalSteps(7 * $this->lines);
-
- // once done, use storage thing to actually store them:
- Log::info(sprintf('Returned %d valid objects from file processor', $this->lines));
-
- $storage = $this->storeObjects($importObjects);
- $this->addStep();
- Log::debug('Back in run()');
-
- Log::debug('Updated job...');
- Log::debug(sprintf('%d journals in $storage->journals', $storage->journals->count()));
- $this->journals = $storage->journals;
- $this->errors = $storage->errors;
-
- Log::debug('Going to call createImportTag()');
-
- // create tag, link tag to all journals:
- $this->createImportTag();
- $this->addStep();
-
- // update job:
- $this->setStatus('finished');
-
- Log::info(sprintf('Done with import job %s', $this->job->key));
-
- return true;
+ throw new FireflyException(sprintf('Import routine cannot handle status "%s"', $this->importJob->status)); // @codeCoverageIgnore
}
/**
- * @param ImportJob $job
+ * @param ImportJob $importJob
+ *
+ * @return void
*/
- public function setJob(ImportJob $job)
+ public function setImportJob(ImportJob $importJob): void
{
- $this->job = $job;
+ $this->importJob = $importJob;
$this->repository = app(ImportJobRepositoryInterface::class);
- $this->repository->setUser($job->user);
+ $this->repository->setUser($importJob->user);
}
/**
- * @return Collection
- */
- protected function getImportObjects(): Collection
- {
- $objects = new Collection;
- $fileType = $this->getConfig()['file-type'] ?? 'csv';
- // will only respond to "file"
- $class = config(sprintf('import.options.file.processors.%s', $fileType));
- /** @var FileProcessorInterface $processor */
- $processor = app($class);
- $processor->setJob($this->job);
-
- if ('configured' === $this->getStatus()) {
- // set job as "running"...
- $this->setStatus('running');
-
- Log::debug('Job is configured, start with run()');
- $processor->run();
- $objects = $processor->getObjects();
- }
-
- return $objects;
- }
-
- /**
- * Shorthand method.
- */
- private function addStep()
- {
- $this->repository->addStepsDone($this->job, 1);
- }
-
- /**
- * Shorthand
+ * Return the appropriate file routine handler for
+ * the file type of the job.
*
- * @param int $steps
+ * @return FileProcessorInterface
*/
- private function addTotalSteps(int $steps)
+ private function getProcessor(): FileProcessorInterface
{
- $this->repository->addTotalSteps($this->job, $steps);
- }
+ $config = $this->repository->getConfiguration($this->importJob);
+ $type = $config['file-type'] ?? 'csv';
+ $class = config(sprintf('import.options.file.processors.%s', $type));
- /**
- *
- */
- private function createImportTag(): Tag
- {
- Log::debug('Now in createImportTag()');
-
- if ($this->journals->count() < 1) {
- Log::info(sprintf('Will not create tag, %d journals imported.', $this->journals->count()));
-
- return new Tag;
- }
- $this->addTotalSteps($this->journals->count() + 2);
-
- /** @var TagRepositoryInterface $repository */
- $repository = app(TagRepositoryInterface::class);
- $repository->setUser($this->job->user);
- $data = [
- 'tag' => trans('import.import_with_key', ['key' => $this->job->key]),
- 'date' => new Carbon,
- 'description' => null,
- 'latitude' => null,
- 'longitude' => null,
- 'zoomLevel' => null,
- 'tagMode' => 'nothing',
- ];
- $tag = $repository->store($data);
- $this->addStep();
- $extended = $this->getExtendedStatus();
- $extended['tag'] = $tag->id;
- $this->setExtendedStatus($extended);
-
- Log::debug(sprintf('Created tag #%d ("%s")', $tag->id, $tag->tag));
- Log::debug('Looping journals...');
- $journalIds = $this->journals->pluck('id')->toArray();
- $tagId = $tag->id;
- foreach ($journalIds as $journalId) {
- Log::debug(sprintf('Linking journal #%d to tag #%d...', $journalId, $tagId));
- DB::table('tag_transaction_journal')->insert(['transaction_journal_id' => $journalId, 'tag_id' => $tagId]);
- $this->addStep();
- }
- Log::info(sprintf('Linked %d journals to tag #%d ("%s")', $this->journals->count(), $tag->id, $tag->tag));
- $this->addStep();
-
- return $tag;
- }
-
- /**
- * Shorthand method
- *
- * @return array
- */
- private function getConfig(): array
- {
- return $this->repository->getConfiguration($this->job);
- }
-
- /**
- * @return array
- */
- private function getExtendedStatus(): array
- {
- return $this->repository->getExtendedStatus($this->job);
- }
-
- /**
- * Shorthand method.
- *
- * @return string
- */
- private function getStatus(): string
- {
- return $this->repository->getStatus($this->job);
- }
-
- /**
- * @param array $extended
- */
- private function setExtendedStatus(array $extended): void
- {
- $this->repository->setExtendedStatus($this->job, $extended);
- }
-
- /**
- * Shorthand
- *
- * @param string $status
- */
- private function setStatus(string $status): void
- {
- $this->repository->setStatus($this->job, $status);
- }
-
- /**
- * Shorthand
- *
- * @param int $steps
- */
- private function setTotalSteps(int $steps)
- {
- $this->repository->setTotalSteps($this->job, $steps);
- }
-
- /**
- * @param Collection $objects
- *
- * @return ImportStorage
- */
- private function storeObjects(Collection $objects): ImportStorage
- {
- $config = $this->getConfig();
- $storage = new ImportStorage;
- $storage->setJob($this->job);
- $storage->setDateFormat($config['date-format']);
- $storage->setObjects($objects);
- $storage->store();
- Log::info('Back in storeObjects()');
-
- return $storage;
+ return app($class);
}
}
diff --git a/app/Import/Routine/RoutineInterface.php b/app/Import/Routine/RoutineInterface.php
index ef2d25515b..aad9c4854a 100644
--- a/app/Import/Routine/RoutineInterface.php
+++ b/app/Import/Routine/RoutineInterface.php
@@ -22,8 +22,8 @@ declare(strict_types=1);
namespace FireflyIII\Import\Routine;
+use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\ImportJob;
-use Illuminate\Support\Collection;
/**
* Interface RoutineInterface
@@ -31,29 +31,18 @@ use Illuminate\Support\Collection;
interface RoutineInterface
{
/**
- * @return Collection
- */
- public function getErrors(): Collection;
-
- /**
- * @return Collection
- */
- public function getJournals(): Collection;
-
- /**
- * @return int
- */
- public function getLines(): int;
-
- /**
- * @return bool
- */
- public function run(): bool;
-
- /**
- * @param ImportJob $job
+ * At the end of each run(), the import routine must set the job to the expected status.
*
- * @return mixed
+ * The final status of the routine must be "provider_finished".
+ *
+ * @throws FireflyException
*/
- public function setJob(ImportJob $job);
+ public function run(): void;
+
+ /**
+ * @param ImportJob $importJob
+ *
+ * @return void
+ */
+ public function setImportJob(ImportJob $importJob): void;
}
diff --git a/app/Import/Routine/SpectreRoutine.php b/app/Import/Routine/SpectreRoutine.php
index 3147f7788f..1c51d8d697 100644
--- a/app/Import/Routine/SpectreRoutine.php
+++ b/app/Import/Routine/SpectreRoutine.php
@@ -22,572 +22,101 @@ declare(strict_types=1);
namespace FireflyIII\Import\Routine;
-use Carbon\Carbon;
-use DB;
-use Exception;
use FireflyIII\Exceptions\FireflyException;
-use FireflyIII\Import\Object\ImportJournal;
-use FireflyIII\Import\Storage\ImportStorage;
use FireflyIII\Models\ImportJob;
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
-use FireflyIII\Repositories\Tag\TagRepositoryInterface;
-use FireflyIII\Services\Spectre\Exception\SpectreException;
-use FireflyIII\Services\Spectre\Object\Account;
-use FireflyIII\Services\Spectre\Object\Customer;
-use FireflyIII\Services\Spectre\Object\Login;
-use FireflyIII\Services\Spectre\Object\Token;
-use FireflyIII\Services\Spectre\Object\Transaction;
-use FireflyIII\Services\Spectre\Request\CreateTokenRequest;
-use FireflyIII\Services\Spectre\Request\ListAccountsRequest;
-use FireflyIII\Services\Spectre\Request\ListCustomersRequest;
-use FireflyIII\Services\Spectre\Request\ListLoginsRequest;
-use FireflyIII\Services\Spectre\Request\ListTransactionsRequest;
-use FireflyIII\Services\Spectre\Request\NewCustomerRequest;
-use Illuminate\Support\Collection;
+use FireflyIII\Support\Import\Routine\Spectre\StageImportDataHandler;
+use FireflyIII\Support\Import\Routine\Spectre\StageAuthenticatedHandler;
+use FireflyIII\Support\Import\Routine\Spectre\StageNewHandler;
use Log;
-use Preferences;
/**
- * Class FileRoutine
+ * Class SpectreRoutine
*/
class SpectreRoutine implements RoutineInterface
{
- /** @var Collection */
- public $errors;
- /** @var Collection */
- public $journals;
- /** @var int */
- public $lines = 0;
+
/** @var ImportJob */
- private $job;
+ private $importJob;
/** @var ImportJobRepositoryInterface */
private $repository;
/**
- * ImportRoutine constructor.
- */
- public function __construct()
- {
- $this->journals = new Collection;
- $this->errors = new Collection;
- }
-
- /**
- * @return Collection
- */
- public function getErrors(): Collection
- {
- return $this->errors;
- }
-
- /**
- * @return Collection
- */
- public function getJournals(): Collection
- {
- return $this->journals;
- }
-
- /**
- * @return int
- */
- public function getLines(): int
- {
- return $this->lines;
- }
-
- /**
- * A Spectre job that ends up here is either "configured" or "running", and will be set to "running"
- * when it is "configured".
+ * At the end of each run(), the import routine must set the job to the expected status.
*
- * Job has several stages, stored in extended status key 'stage'
- *
- * initial: just begun, nothing happened. action: get a customer and a token. Next status: has-token
- * has-token: redirect user to sandstorm, make user login. set job to: user-logged-in
- * user-logged-in: customer has an attempt. action: analyse/get attempt and go for next status.
- * if attempt failed: job status is error, save a warning somewhere?
- * if success, try to get accounts. Save in config key 'accounts'. set status: have-accounts and "configuring"
- *
- * have-accounts: make user link accounts and select accounts to import from.
- *
- * If job is "configuring" and stage "have-accounts" then present the accounts and make user link them to
- * own asset accounts. Store this mapping, set config to "have-account-mapping" and job status configured".
- *
- * have-account-mapping: start downloading transactions?
- *
- *
- * @return bool
- *
- * @throws FireflyException
- * @throws SpectreException
- * @throws \Illuminate\Container\EntryNotFoundException
- */
- public function run(): bool
- {
- if ('configured' === $this->getStatus()) {
- $this->repository->updateStatus($this->job, 'running');
- }
- Log::info(sprintf('Start with import job %s using Spectre.', $this->job->key));
- set_time_limit(0);
-
- // check if job has token first!
- $stage = $this->getConfig()['stage'] ?? 'unknown';
-
- switch ($stage) {
- case 'initial':
- // get customer and token:
- $this->runStageInitial();
- break;
- case 'has-token':
- // import routine does nothing at this point:
- break;
- case 'user-logged-in':
- $this->runStageLoggedIn();
- break;
- case 'have-account-mapping':
- $this->runStageHaveMapping();
- break;
- default:
- throw new FireflyException(sprintf('Cannot handle stage %s', $stage));
- }
-
- return true;
- }
-
- /**
- * @param ImportJob $job
- */
- public function setJob(ImportJob $job)
- {
- $this->job = $job;
- $this->repository = app(ImportJobRepositoryInterface::class);
- $this->repository->setUser($job->user);
- }
-
- /**
- * @return Customer
- *
- * @throws \FireflyIII\Exceptions\FireflyException
- * @throws \FireflyIII\Services\Spectre\Exception\SpectreException
- * @throws \Illuminate\Container\EntryNotFoundException
- */
- protected function createCustomer(): Customer
- {
- $newCustomerRequest = new NewCustomerRequest($this->job->user);
- $customer = null;
- try {
- $newCustomerRequest->call();
- $customer = $newCustomerRequest->getCustomer();
- } catch (Exception $e) {
- // already exists, must fetch customer instead.
- Log::warning(sprintf('Customer exists already for user, fetch it: %s', $e->getMessage()));
- }
- if (null === $customer) {
- $getCustomerRequest = new ListCustomersRequest($this->job->user);
- $getCustomerRequest->call();
- $customers = $getCustomerRequest->getCustomers();
- /** @var Customer $current */
- foreach ($customers as $current) {
- if ('default_ff3_customer' === $current->getIdentifier()) {
- $customer = $current;
- break;
- }
- }
- }
-
- Preferences::setForUser($this->job->user, 'spectre_customer', $customer->toArray());
-
- return $customer;
- }
-
- /**
- * @return Customer
- *
- * @throws FireflyException
- * @throws SpectreException
- * @throws \Illuminate\Container\EntryNotFoundException
- */
- protected function getCustomer(): Customer
- {
- $config = $this->getConfig();
- if (null !== $config['customer']) {
- $customer = new Customer($config['customer']);
-
- return $customer;
- }
-
- $customer = $this->createCustomer();
- $config['customer'] = [
- 'id' => $customer->getId(),
- 'identifier' => $customer->getIdentifier(),
- 'secret' => $customer->getSecret(),
- ];
- $this->setConfig($config);
-
- return $customer;
- }
-
- /**
- * @param Customer $customer
- * @param string $returnUri
- *
- * @return Token
- *
- * @throws \FireflyIII\Exceptions\FireflyException
- * @throws \FireflyIII\Services\Spectre\Exception\SpectreException
- * @throws \Illuminate\Container\EntryNotFoundException
- */
- protected function getToken(Customer $customer, string $returnUri): Token
- {
- $request = new CreateTokenRequest($this->job->user);
- $request->setUri($returnUri);
- $request->setCustomer($customer);
- $request->call();
- Log::debug('Call to get token is finished');
-
- return $request->getToken();
- }
-
- /**
- * @throws FireflyException
- * @throws SpectreException
- * @throws \Illuminate\Container\EntryNotFoundException
- */
- protected function runStageInitial(): void
- {
- Log::debug('In runStageInitial()');
-
- // create customer if user does not have one:
- $customer = $this->getCustomer();
- Log::debug(sprintf('Customer ID is %s', $customer->getId()));
-
- // use customer to request a token:
- $uri = route('import.status', [$this->job->key]);
- $token = $this->getToken($customer, $uri);
- Log::debug(sprintf('Token is %s', $token->getToken()));
-
- // update job, give it the token:
- $config = $this->getConfig();
- $config['has-token'] = true;
- $config['token'] = $token->getToken();
- $config['token-expires'] = $token->getExpiresAt()->format('U');
- $config['token-url'] = $token->getConnectUrl();
- $config['stage'] = 'has-token';
- $this->setConfig($config);
-
- Log::debug('Job config is now', $config);
-
- // update job, set status to "configuring".
- $this->setStatus('configuring');
- Log::debug(sprintf('Job status is now %s', $this->job->status));
- $this->addStep();
- }
-
- /**
- * @throws FireflyException
- * @throws SpectreException
- * @throws \Illuminate\Container\EntryNotFoundException
- */
- protected function runStageLoggedIn(): void
- {
- Log::debug('In runStageLoggedIn');
- // list all logins:
- $customer = $this->getCustomer();
- $request = new ListLoginsRequest($this->job->user);
- $request->setCustomer($customer);
- $request->call();
-
- $logins = $request->getLogins();
- /** @var Login $final */
- $final = null;
- // loop logins, find the latest with no error in it:
- $time = 0;
- /** @var Login $login */
- foreach ($logins as $login) {
- $attempt = $login->getLastAttempt();
- $attemptTime = (int)$attempt->getCreatedAt()->format('U');
- if ($attemptTime > $time && null === $attempt->getFailErrorClass()) {
- $time = $attemptTime;
- $final = $login;
- }
- }
- if (null === $final) {
- Log::error('Could not find a valid login for this user.');
- $this->repository->addError($this->job, 0, 'Spectre connection failed. Did you use invalid credentials, press Cancel or failed the 2FA challenge?');
- $this->repository->setStatus($this->job, 'error');
-
- return;
- }
- $this->addStep();
-
- // list the users accounts using this login.
- $accountRequest = new ListAccountsRequest($this->job->user);
- $accountRequest->setLogin($login);
- $accountRequest->call();
- $accounts = $accountRequest->getAccounts();
-
- // store accounts in job:
- $all = [];
- /** @var Account $account */
- foreach ($accounts as $account) {
- $all[] = $account->toArray();
- }
-
- // update job:
- $config = $this->getConfig();
- $config['accounts'] = $all;
- $config['login'] = $login->toArray();
- $config['stage'] = 'have-accounts';
-
- $this->setConfig($config);
- $this->setStatus('configuring');
- $this->addStep();
- }
-
- /**
- * Shorthand method.
- */
- private function addStep()
- {
- $this->repository->addStepsDone($this->job, 1);
- }
-
- /**
- * Shorthand
- *
- * @param int $steps
- */
- private function addTotalSteps(int $steps)
- {
- $this->repository->addTotalSteps($this->job, $steps);
- }
-
- /**
- * @return array
- */
- private function getConfig(): array
- {
- return $this->repository->getConfiguration($this->job);
- }
-
- /**
- * Shorthand method.
- *
- * @return array
- */
- private function getExtendedStatus(): array
- {
- return $this->repository->getExtendedStatus($this->job);
- }
-
- /**
- * Shorthand method.
- *
- * @return string
- */
- private function getStatus(): string
- {
- return $this->repository->getStatus($this->job);
- }
-
- /**
- * @param array $all
+ * The final status of the routine must be "provider_finished".
*
* @throws FireflyException
*/
- private function importTransactions(array $all)
+ public function run(): void
{
- Log::debug('Going to import transactions');
- $collection = new Collection;
- // create import objects?
- foreach ($all as $accountId => $data) {
- Log::debug(sprintf('Now at account #%d', $accountId));
- /** @var Transaction $transaction */
- foreach ($data['transactions'] as $transaction) {
- Log::debug(sprintf('Now at transaction #%d', $transaction->getId()));
- /** @var Account $account */
- $account = $data['account'];
- $importJournal = new ImportJournal;
- $importJournal->setUser($this->job->user);
- $importJournal->asset->setDefaultAccountId($data['import_id']);
- // call set value a bunch of times for various data entries:
- $tags = [];
- $tags[] = $transaction->getMode();
- $tags[] = $transaction->getStatus();
- if ($transaction->isDuplicated()) {
- $tags[] = 'possibly-duplicated';
- }
- $extra = $transaction->getExtra()->toArray();
- $notes = '';
- // double space for newline in Markdown.
- $notes .= (string)trans('import.imported_from_account', ['account' => $account->getName()]) . ' ' . "\n";
+ Log::debug(sprintf('Now in SpectreRoutine::run() with status "%s" and stage "%s".', $this->importJob->status, $this->importJob->stage));
+ $valid = ['ready_to_run']; // should be only ready_to_run
+ if (\in_array($this->importJob->status, $valid, true)) {
+ switch ($this->importJob->stage) {
+ default:
+ throw new FireflyException(sprintf('SpectreRoutine cannot handle stage "%s".', $this->importJob->stage)); // @codeCoverageIgnore
+ case 'new':
+ // list all of the users logins.
+ $this->repository->setStatus($this->importJob, 'running');
+ /** @var StageNewHandler $handler */
+ $handler = app(StageNewHandler::class);
+ $handler->setImportJob($this->importJob);
+ $handler->run();
- foreach ($extra as $key => $value) {
- switch ($key) {
- case 'account_number':
- $importJournal->setValue(['role' => 'account-number', 'value' => $value]);
- break;
- case 'original_category':
- case 'original_subcategory':
- case 'customer_category_code':
- case 'customer_category_name':
- $tags[] = $value;
- break;
- case 'payee':
- $importJournal->setValue(['role' => 'opposing-name', 'value' => $value]);
- break;
- case 'original_amount':
- $importJournal->setValue(['role' => 'amount_foreign', 'value' => $value]);
- break;
- case 'original_currency_code':
- $importJournal->setValue(['role' => 'foreign-currency-code', 'value' => $value]);
- break;
- default:
- $notes .= $key . ': ' . $value . ' '; // for newline in Markdown.
+ // if count logins is zero, go to authenticate stage
+ if ($handler->getCountLogins() === 0) {
+ $this->repository->setStage($this->importJob, 'do-authenticate');
+ $this->repository->setStatus($this->importJob, 'ready_to_run');
+
+ return;
}
- }
- // hash
- $importJournal->setHash($transaction->getHash());
+ // or return to config to select login.
+ $this->repository->setStage($this->importJob, 'choose-login');
+ $this->repository->setStatus($this->importJob, 'need_job_config');
+ break;
+ case 'do-authenticate':
+ // set job to require config.
+ $this->repository->setStatus($this->importJob, 'need_job_config');
- // account ID (Firefly III account):
- $importJournal->setValue(['role' => 'account-id', 'value' => $data['import_id'], 'mapped' => $data['import_id']]);
+ return;
+ case 'authenticated':
+ $this->repository->setStatus($this->importJob, 'running');
+ // get accounts from login, store in job.
+ /** @var StageAuthenticatedHandler $handler */
+ $handler = app(StageAuthenticatedHandler::class);
+ $handler->setImportJob($this->importJob);
+ $handler->run();
- // description:
- $importJournal->setValue(['role' => 'description', 'value' => $transaction->getDescription()]);
-
- // date:
- $importJournal->setValue(['role' => 'date-transaction', 'value' => $transaction->getMadeOn()->toIso8601String()]);
-
- // amount
- $importJournal->setValue(['role' => 'amount', 'value' => $transaction->getAmount()]);
- $importJournal->setValue(['role' => 'currency-code', 'value' => $transaction->getCurrencyCode()]);
-
- // various meta fields:
- $importJournal->setValue(['role' => 'category-name', 'value' => $transaction->getCategory()]);
- $importJournal->setValue(['role' => 'note', 'value' => $notes]);
- $importJournal->setValue(['role' => 'tags-comma', 'value' => implode(',', $tags)]);
- $collection->push($importJournal);
+ // return to config to select account(s).
+ $this->repository->setStage($this->importJob, 'choose-accounts');
+ $this->repository->setStatus($this->importJob, 'need_job_config');
+ break;
+ case 'go-for-import':
+ // user has chosen account mapping. Should now be ready to import data.
+ $this->repository->setStatus($this->importJob, 'running');
+ $this->repository->setStage($this->importJob, 'do_import');
+ /** @var StageImportDataHandler $handler */
+ $handler = app(StageImportDataHandler::class);
+ $handler->setImportJob($this->importJob);
+ $handler->run();
+ $this->repository->setStatus($this->importJob, 'provider_finished');
+ $this->repository->setStage($this->importJob, 'final');
}
}
- $this->addStep();
- Log::debug(sprintf('Going to try and store all %d them.', $collection->count()));
-
- $this->addTotalSteps(7 * $collection->count());
- // try to store them (seven steps per transaction)
- $storage = new ImportStorage;
-
- $storage->setJob($this->job);
- $storage->setDateFormat('Y-m-d\TH:i:sO');
- $storage->setObjects($collection);
- $storage->store();
- Log::info('Back in importTransactions()');
-
- // link to tag
- /** @var TagRepositoryInterface $repository */
- $repository = app(TagRepositoryInterface::class);
- $repository->setUser($this->job->user);
- $data = [
- 'tag' => trans('import.import_with_key', ['key' => $this->job->key]),
- 'date' => new Carbon,
- 'description' => null,
- 'latitude' => null,
- 'longitude' => null,
- 'zoomLevel' => null,
- 'tagMode' => 'nothing',
- ];
- $tag = $repository->store($data);
- $extended = $this->getExtendedStatus();
- $extended['tag'] = $tag->id;
- $this->setExtendedStatus($extended);
-
- Log::debug(sprintf('Created tag #%d ("%s")', $tag->id, $tag->tag));
- Log::debug('Looping journals...');
- $journalIds = $storage->journals->pluck('id')->toArray();
- $tagId = $tag->id;
- $this->addTotalSteps(\count($journalIds));
-
- foreach ($journalIds as $journalId) {
- Log::debug(sprintf('Linking journal #%d to tag #%d...', $journalId, $tagId));
- DB::table('tag_transaction_journal')->insert(['transaction_journal_id' => $journalId, 'tag_id' => $tagId]);
- $this->addStep();
- }
- Log::info(sprintf('Linked %d journals to tag #%d ("%s")', $storage->journals->count(), $tag->id, $tag->tag));
-
- // set status to "finished"?
- // update job:
- $this->setStatus('finished');
- $this->addStep();
-
}
/**
- * @throws FireflyException
- * @throws SpectreException
- * @throws \Illuminate\Container\EntryNotFoundException
- */
- private function runStageHaveMapping()
- {
- $config = $this->getConfig();
- $accounts = $config['accounts'] ?? [];
- $all = [];
- $count = 0;
- /** @var array $accountArray */
- foreach ($accounts as $accountArray) {
- $account = new Account($accountArray);
- $importId = (int)($config['accounts-mapped'][$account->getId()] ?? 0.0);
- $doImport = 0 !== $importId;
- if (!$doImport) {
- Log::debug(sprintf('Will NOT import from Spectre account #%d ("%s")', $account->getId(), $account->getName()));
- continue;
- }
- // grab all transactions
- $listTransactionsRequest = new ListTransactionsRequest($this->job->user);
- $listTransactionsRequest->setAccount($account);
- $listTransactionsRequest->call();
- $transactions = $listTransactionsRequest->getTransactions();
- $all[$account->getId()] = [
- 'account' => $account,
- 'import_id' => $importId,
- 'transactions' => $transactions,
- ];
- $count += \count($transactions);
- }
- Log::debug(sprintf('Total number of transactions: %d', $count));
- $this->addStep();
-
- $this->importTransactions($all);
- }
-
- /**
- * Shorthand.
+ * @param ImportJob $importJob
*
- * @param array $config
+ * @return void
*/
- private function setConfig(array $config): void
+ public function setImportJob(ImportJob $importJob): void
{
- $this->repository->setConfiguration($this->job, $config);
-
+ $this->importJob = $importJob;
+ $this->repository = app(ImportJobRepositoryInterface::class);
+ $this->repository->setUser($importJob->user);
}
- /**
- * Shorthand method.
- *
- * @param array $extended
- */
- private function setExtendedStatus(array $extended): void
- {
- $this->repository->setExtendedStatus($this->job, $extended);
-
- }
-
- /**
- * Shorthand.
- *
- * @param string $status
- */
- private function setStatus(string $status): void
- {
- $this->repository->setStatus($this->job, $status);
- }
}
diff --git a/app/Import/Specifics/AbnAmroDescription.php b/app/Import/Specifics/AbnAmroDescription.php
index 47ab96db0a..b714734836 100644
--- a/app/Import/Specifics/AbnAmroDescription.php
+++ b/app/Import/Specifics/AbnAmroDescription.php
@@ -36,19 +36,21 @@ class AbnAmroDescription implements SpecificInterface
public $row;
/**
+ * @codeCoverageIgnore
* @return string
*/
public static function getDescription(): string
{
- return 'Fixes possible problems with ABN Amro descriptions.';
+ return 'import.specific_abn_descr';
}
/**
+ * @codeCoverageIgnore
* @return string
*/
public static function getName(): string
{
- return 'ABN Amro description';
+ return 'import.specific_abn_name';
}
/**
@@ -81,7 +83,7 @@ class AbnAmroDescription implements SpecificInterface
*
* @return bool true if the description is GEA/BEA-format, false otherwise
*/
- protected function parseABNAMRODescription()
+ protected function parseABNAMRODescription(): bool
{
// See if the current description is formatted in ABN AMRO format
if (preg_match('/ABN AMRO.{24} (.*)/', $this->row[7], $matches)) {
@@ -99,7 +101,7 @@ class AbnAmroDescription implements SpecificInterface
*
* @return bool true if the description is GEA/BEAformat, false otherwise
*/
- protected function parseGEABEADescription()
+ protected function parseGEABEADescription(): bool
{
// See if the current description is formatted in GEA/BEA format
if (preg_match('/([BG]EA) +(NR:[a-zA-Z:0-9]+) +([0-9.\/]+) +([^,]*)/', $this->row[7], $matches)) {
@@ -124,7 +126,7 @@ class AbnAmroDescription implements SpecificInterface
*
* @return bool true if the description is SEPA format, false otherwise
*/
- protected function parseSepaDescription()
+ protected function parseSepaDescription(): bool
{
// See if the current description is formatted as a SEPA plain description
if (preg_match('/^SEPA(.{28})/', $this->row[7], $matches)) {
@@ -178,7 +180,7 @@ class AbnAmroDescription implements SpecificInterface
*
* @return bool true if the description is TRTP format, false otherwise
*/
- protected function parseTRTPDescription()
+ protected function parseTRTPDescription(): bool
{
// See if the current description is formatted in TRTP format
if (preg_match_all('!\/([A-Z]{3,4})\/([^/]*)!', $this->row[7], $matches, PREG_SET_ORDER)) {
@@ -196,7 +198,7 @@ class AbnAmroDescription implements SpecificInterface
switch (strtoupper($key)) {
case 'NAME':
- $this->row[8] = $name = $value;
+ $this->row[8] = $value;
break;
case 'REMI':
$newDescription = $value;
diff --git a/app/Import/Specifics/IngDescription.php b/app/Import/Specifics/IngDescription.php
index 4277a31df2..599f22d669 100644
--- a/app/Import/Specifics/IngDescription.php
+++ b/app/Import/Specifics/IngDescription.php
@@ -38,19 +38,21 @@ class IngDescription implements SpecificInterface
public $row;
/**
+ * @codeCoverageIgnore
* @return string
*/
public static function getDescription(): string
{
- return 'Create better descriptions in ING import files.';
+ return 'import.specific_ing_descr';
}
/**
+ * @codeCoverageIgnore
* @return string
*/
public static function getName(): string
{
- return 'ING description';
+ return 'import.specific_ing_name';
}
/**
@@ -84,41 +86,29 @@ class IngDescription implements SpecificInterface
/**
* Add the Opposing name from cell 1 in the description for Betaalautomaten
* Otherwise the description is only: 'Pasvolgnr:
+
+
+
storage/logs pour obtenir des instructions.',
'two_factor_lost_fix_owner' => 'Dans le cas contraire, contactez le propriétaire du site par courriel :site_owner et demandez-lui de réinitialiser votre authentification à deux facteurs.',
- 'warning_much_data' => ':days de données peuvent prendre un certain temps à charger.',
+ 'warning_much_data' => ':days jours de données peuvent prendre un certain temps à charger.',
'registered' => 'Vous avez été enregistré avec succès !',
'Default asset account' => 'Compte d’actif par défaut',
'no_budget_pointer' => 'Vous semblez n’avoir encore aucun budget. Vous devez en créer un sur la page des budgets. Les budgets peuvent vous aider à garder une trace des dépenses.',
@@ -179,6 +180,7 @@ return [
'authorization_request_intro' => ':client demande l\'autorisation d\'accéder à votre administration financière. Souhaitez-vous autoriser :client à accéder à ces enregistrements?',
'scopes_will_be_able' => 'Cette application pourra :',
'button_authorize' => 'Autoriser',
+ 'none_in_select_list' => '(aucun)',
// check for updates:
'update_check_title' => 'Vérifier les mises à jour',
@@ -267,10 +269,10 @@ return [
'move_rule_group_down' => 'Descendre le groupe de règles',
'save_rules_by_moving' => 'Enregistrer ces règles en les déplaçant vers un autre groupe de règles :',
'make_new_rule' => 'Créer une nouvelle règle dans le groupe de règles ":title"',
- 'rule_is_strict' => 'strict rule',
- 'rule_is_not_strict' => 'non-strict rule',
+ 'rule_is_strict' => 'règle stricte',
+ 'rule_is_not_strict' => 'règle non stricte',
'rule_help_stop_processing' => 'Lorsque vous cochez cette case, les règles suivantes de ce groupe ne seront pas exécutées.',
- 'rule_help_strict' => 'In strict rules ALL triggers must fire for the action(s) to be executed. In non-strict rules, ANY trigger is enough for the action(s) to be executed.',
+ 'rule_help_strict' => 'Dans les règles strictes, TOUS les déclencheurs doivent être activés pour les actions à exécuter. Dans les règles non strictes, N\'IMPORTE QUEL déclencheur est suffisant pour que l\'action soit exécutée.',
'rule_help_active' => 'Les règles inactives ne se déclencheront jamais.',
'stored_new_rule' => 'Nouvelle règle créée avec le titre ":title"',
'deleted_rule' => 'Règle supprimée avec le titre ":title"',
@@ -541,7 +543,7 @@ return [
'attachment_deleted' => 'Pièce jointe ":name" supprimée',
'attachment_updated' => 'Pièce jointe ":name" mise à jour',
'upload_max_file_size' => 'Taille maximum du fichier : :size',
- 'list_all_attachments' => 'List of all attachments',
+ 'list_all_attachments' => 'Liste de toutes les pièces jointes',
// transaction index
'title_expenses' => 'Dépenses',
@@ -584,7 +586,7 @@ return [
'converted_to_Deposit' => 'La transaction a été convertie en dépôt',
'converted_to_Transfer' => 'La transaction a été convertie en transfert',
'invalid_convert_selection' => 'Le compte que vous avez sélectionné est déjà utilisé dans cette transaction ou n\'existe pas.',
- 'source_or_dest_invalid' => 'Cannot find the correct transaction details. Conversion is not possible.',
+ 'source_or_dest_invalid' => 'Impossible de trouver les détails de transaction corrects. La conversion n\'est pas possible.',
// create new stuff:
'create_new_withdrawal' => 'Créer une nouvelle dépense',
@@ -641,8 +643,8 @@ return [
'over_budget_warn' => ' Normalement vous budgétez :amount par jour. Là c\'est :over_amount par jour.',
// bills:
- 'match_between_amounts' => 'Bill matches transactions between :low and :high.',
- 'bill_related_rules' => 'Rules related to this bill',
+ 'match_between_amounts' => 'Factures correspondes à des transactions entre :low et :high.',
+ 'bill_related_rules' => 'Règles reliées à cette facture',
'repeats' => 'Répétitions',
'connected_journals' => 'Opérations liées',
'auto_match_on' => 'Automatiquement mis en correspondance par Firefly III',
@@ -652,13 +654,13 @@ return [
'deleted_bill' => 'Facture ":name" supprimée',
'edit_bill' => 'Modifier la facture : ":name"',
'more' => 'Plus',
- 'rescan_old' => 'Run rules again, on all transactions',
+ 'rescan_old' => 'Exécuter les règles à nouveau, sur toutes les transactions',
'update_bill' => 'Mettre à jour la facture',
'updated_bill' => 'Facture ":name" mise à jour',
'store_new_bill' => 'Créer une nouvelle facture',
'stored_new_bill' => 'Nouvelle facture ":name" créée',
'cannot_scan_inactive_bill' => 'Les factures inactives ne peuvent pas être analysées.',
- 'rescanned_bill' => 'Rescanned everything, and linked :total transaction(s) to the bill.',
+ 'rescanned_bill' => 'Tout a été redéfini et lié aux :total transaction(s) de la facture.',
'average_bill_amount_year' => 'Montant moyen des factures (Â :year)',
'average_bill_amount_overall' => 'Montant moyen de la facture (global)',
'bill_is_active' => 'Facture en cours',
@@ -666,6 +668,7 @@ return [
'bill_will_automatch' => 'La facture sera automatiquement liée aux transactions correspondantes',
'skips_over' => 'saute',
'bill_store_error' => 'Une erreur inattendue s\'est produite lors du stockage de votre nouvelle facture. Veuillez vérifier les fichiers journaux',
+ 'list_inactive_rule' => 'règle inactive',
// accounts:
'details_for_asset' => 'Détails pour le compte d’actif ":name"',
@@ -699,7 +702,7 @@ return [
'delete_reconciliation' => 'Supprimer le rapprochement',
'update_reconciliation' => 'Mettre à jour le rapprochement',
'amount_cannot_be_zero' => 'Le montant ne peut pas être zéro',
- 'end_of_reconcile_period' => 'Fin de la période de rapptrochement : :period',
+ 'end_of_reconcile_period' => 'Fin de la période de rapprochement: :period',
'start_of_reconcile_period' => 'Début de la période de rapprochement : :period',
'start_balance' => 'Solde initial',
'end_balance' => 'Solde de clotûre',
@@ -801,6 +804,7 @@ return [
'opt_group_savingAsset' => 'Comptes d\'épargne',
'opt_group_sharedAsset' => 'Comptes d\'actifs partagés',
'opt_group_ccAsset' => 'Cartes de crédit',
+ 'opt_group_cashWalletAsset' => 'Portefeuilles d\'argent',
'notes' => 'Notes',
'unknown_journal_error' => 'Impossible de stocker la transaction. Veuillez vérifier les fichiers journaux.',
@@ -812,10 +816,11 @@ return [
'savings_balance_text' => 'Firefly III créera automatiquement un compte d\'épargne pour vous. Par défaut, il n\'y aura pas d\'argent dans votre compte d\'épargne, mais si vous le dites à Firefly III, le solde sera stocké en tant que tel.',
'finish_up_new_user' => 'C\'est tout ! Vous pouvez continuer en appuyant sur Envoyer. Vous passerez à l\'index de Firefly III.',
'stored_new_accounts_new_user' => 'Super ! Vos nouveaux comptes ont été créés.',
- 'set_preferred_language' => 'If you prefer to use Firefly III in another language, please indicate so here.',
- 'language' => 'Language',
- 'new_savings_account' => ':bank_name savings account',
- 'cash_wallet' => 'Cash wallet',
+ 'set_preferred_language' => 'Si vous préférez utiliser Firefly III dans une autre langue, veuillez l\'indiquer ici.',
+ 'language' => 'Langage',
+ 'new_savings_account' => ':bank_name compte d\'épargne',
+ 'cash_wallet' => 'Porte-monnaie',
+ 'currency_not_present' => 'If the currency you normally use is not listed do not worry. You can create your own currencies under Options > Currencies.',
// home page:
'yourAccounts' => 'Vos comptes',
@@ -964,7 +969,7 @@ return [
'account_role_sharedAsset' => 'Compte d\'actif partagé',
'account_role_savingAsset' => 'Compte d’épargne',
'account_role_ccAsset' => 'Carte de crédit',
- 'account_role_cashWalletAsset' => 'Cash wallet',
+ 'account_role_cashWalletAsset' => 'Porte-monnaie',
'budget_chart_click' => 'Cliquez sur le nom du budget dans le tableau ci-dessus pour voir un graphique.',
'category_chart_click' => 'Cliquez sur un nom de catégorie dans le tableau ci-dessus pour voir un graphique.',
'in_out_accounts' => 'Gagné et dépensé par compte',
@@ -1013,6 +1018,7 @@ return [
'remove_money_from_piggy_title' => 'Retirer l’argent de la tirelire ":name"',
'add' => 'Ajouter',
'no_money_for_piggy' => 'Vous n\'avez pas d\'argent à placer dans cette tirelire.',
+ 'suggested_savings_per_month' => 'Suggested per month',
'remove' => 'Enlever',
'max_amount_add' => 'Le montant maximum que vous pouvez ajouter est',
@@ -1024,7 +1030,7 @@ return [
'events' => 'Evènements',
'target_amount' => 'Montant cible',
'start_date' => 'Date de début',
- 'no_start_date' => 'No start date',
+ 'no_start_date' => 'Pas de date de début',
'target_date' => 'Date cible',
'no_target_date' => 'Aucune date butoir',
'table' => 'Tableau',
@@ -1066,7 +1072,7 @@ return [
'total_size' => 'taille totale',
'budget_or_budgets' => 'budget(s)',
'budgets_with_limits' => 'budget(s) avec montant configuré',
- 'nr_of_rules_in_total_groups' => ':count_rules règle(s) dans :count_groups groupe(s) de règles',
+ 'nr_of_rules_in_total_groups' => ':count_rules règle(s) dans :count_groups groupe(s) de règles',
'tag_or_tags' => 'tag·s',
'configuration_updated' => 'La configuration a été mise à jour',
'setting_is_demo_site' => 'Site de démonstration',
@@ -1148,27 +1154,9 @@ return [
'no_edit_multiple_left' => 'Vous n\'avez sélectionné aucune transaction valide à éditer.',
'cannot_convert_split_journal' => 'Vous ne pouvez pas convertir une transaction ventilée',
- // import bread crumbs and titles:
- 'import' => 'Import',
- 'import_data' => 'Importer des données',
- 'import_general_index_file' => 'Importer un fichier',
- 'import_from_bunq' => 'Importer depuis bunq',
- 'import_using_spectre' => 'Importer en utilisant Spectre',
- 'import_using_plaid' => 'Importer en utilisant Plaid',
- 'import_config_bread_crumb' => 'Configurez votre import',
-
- // import index page:
+ // Import page (general strings only)
'import_index_title' => 'Importer des données dans Firefly III',
- 'import_index_sub_title' => 'Index',
- 'import_general_index_intro' => 'Bienvenue dans la routine d\'importation de Firefly III. Il existe différentes façons d\'importer des données dans Firefly III, affichées ici sous forme de boutons.',
- 'upload_error' => 'Le fichier que vous avez téléchargé n\'a pas pu être traité. Peut-être qu\'il s\'agit d\'un type de fichier ou d\'un encodage invalide. Plus d\'informations dans les fichiers journaux.',
- 'reset_import_settings_title' => 'Reset import configuration',
- 'reset_import_settings_text' => 'You can use these links to reset your import settings for specific providers. This is useful when bad settings stop you from importing data.',
- 'reset_settings_bunq' => 'Remove bunq API key, local external IP address and bunq related RSA keys.',
- 'reset_settings_spectre' => 'Remove Spectre secrets and ID\'s. This will also remove your Spectre keypair. Remember to update the new one.',
- 'settings_reset_for_bunq' => 'Bunq settings reset.',
- 'settings_reset_for_spectre' => 'Spectre settings reset.',
-
+ 'import_data' => 'Importer des données',
// sandstorm.io errors and messages:
'sandstorm_not_available' => 'Cette fonction n\'est pas disponible lorsque vous utilisez Firefly III dans un environnement Sandstorm.io.',
diff --git a/resources/lang/fr_FR/form.php b/resources/lang/fr_FR/form.php
index a5c0395e57..5c57f4717a 100644
--- a/resources/lang/fr_FR/form.php
+++ b/resources/lang/fr_FR/form.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
// new user:
'bank_name' => 'Nom de la banque',
@@ -184,6 +185,13 @@ return [
'blocked' => 'Est bloqué?',
'blocked_code' => 'Raison du blocage',
+ // import
+ 'apply_rules' => 'Apply rules',
+ 'artist' => 'Artist',
+ 'album' => 'Album',
+ 'song' => 'Song',
+
+
// admin
'domain' => 'Domaine',
'single_user_mode' => 'Désactiver le formulaire d\'inscription',
diff --git a/resources/lang/fr_FR/import.php b/resources/lang/fr_FR/import.php
index b12206bc30..a111bb834e 100644
--- a/resources/lang/fr_FR/import.php
+++ b/resources/lang/fr_FR/import.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
- // status of import:
+ // ALL breadcrumbs and subtitles:
+ 'index_breadcrumb' => 'Import data into Firefly III',
+ 'prerequisites_breadcrumb_fake' => 'Prerequisites for the fake import provider',
+ 'prerequisites_breadcrumb_spectre' => 'Prerequisites for Spectre',
+ 'prerequisites_breadcrumb_bunq' => 'Prerequisites for bunq',
+ 'job_configuration_breadcrumb' => 'Configuration for ":key"',
+ 'job_status_breadcrumb' => 'Import status for ":key"',
+ 'cannot_create_for_provider' => 'Firefly III cannot create a job for the ":provider"-provider.',
+
+ // index page:
+ 'general_index_title' => 'Import a file',
+ 'general_index_intro' => 'Welcome to Firefly III\'s import routine. There are a few ways of importing data into Firefly III, displayed here as buttons.',
+ // import provider strings (index):
+ 'button_fake' => 'Fake an import',
+ 'button_file' => 'Import a file',
+ 'button_bunq' => 'Import from bunq',
+ 'button_spectre' => 'Import using Spectre',
+ 'button_plaid' => 'Import using Plaid',
+ 'button_yodlee' => 'Import using Yodlee',
+ 'button_quovo' => 'Import using Quovo',
+ // global config box (index)
+ 'global_config_title' => 'Global import configuration',
+ 'global_config_text' => 'In the future, this box will feature preferences that apply to ALL import providers above.',
+ // prerequisites box (index)
+ 'need_prereq_title' => 'Import prerequisites',
+ 'need_prereq_intro' => 'Some import methods need your attention before they can be used. For example, they might require special API keys or application secrets. You can configure them here. The icon indicates if these prerequisites have been met.',
+ 'do_prereq_fake' => 'Prerequisites for the fake provider',
+ 'do_prereq_file' => 'Prerequisites for file imports',
+ 'do_prereq_bunq' => 'Prerequisites for imports from bunq',
+ 'do_prereq_spectre' => 'Prerequisites for imports using Spectre',
+ 'do_prereq_plaid' => 'Prerequisites for imports using Plaid',
+ 'do_prereq_yodlee' => 'Prerequisites for imports using Yodlee',
+ 'do_prereq_quovo' => 'Prerequisites for imports using Quovo',
+ // provider config box (index)
+ 'can_config_title' => 'Import configuration',
+ 'can_config_intro' => 'Some import methods can be configured to your liking. They have extra settings you can tweak.',
+ 'do_config_fake' => 'Configuration for the fake provider',
+ 'do_config_file' => 'Configuration for file imports',
+ 'do_config_bunq' => 'Configuration for bunq imports',
+ 'do_config_spectre' => 'Configuration for imports from Spectre',
+ 'do_config_plaid' => 'Configuration for imports from Plaid',
+ 'do_config_yodlee' => 'Configuration for imports from Yodlee',
+ 'do_config_quovo' => 'Configuration for imports from Quovo',
+
+ // prerequisites:
+ 'prereq_fake_title' => 'Prerequisites for an import from the fake import provider',
+ 'prereq_fake_text' => 'This fake provider requires a fake API key. It must be 32 characters long. You can use this one: 123456789012345678901234567890AA',
+ 'prereq_spectre_title' => 'Prerequisites for an import using the Spectre API',
+ 'prereq_spectre_text' => 'In order to import data using the Spectre API (v4), you must provide Firefly III with two secret values. They can be found on the secrets page.',
+ 'prereq_spectre_pub' => 'Likewise, the Spectre API needs to know the public key you see below. Without it, it will not recognize you. Please enter this public key on your secrets page.',
+ 'prereq_bunq_title' => 'Prerequisites for an import from bunq',
+ 'prereq_bunq_text' => 'In order to import from bunq, you need to obtain an API key. You can do this through the app. Please note that the import function for bunq is in BETA. It has only been tested against the sandbox API.',
+ 'prereq_bunq_ip' => 'bunq requires your externally facing IP address. Firefly III has tried to fill this in using the ipify service. Make sure this IP address is correct, or the import will fail.',
+ // prerequisites success messages:
+ 'prerequisites_saved_for_fake' => 'Fake API key stored successfully!',
+ 'prerequisites_saved_for_spectre' => 'App ID and secret stored!',
+ 'prerequisites_saved_for_bunq' => 'API key and IP stored!',
+
+ // job configuration:
+ 'job_config_apply_rules_title' => 'Job configuration - apply your rules?',
+ 'job_config_apply_rules_text' => 'Once the fake provider has run, your rules can be applied to the transactions. This adds time to the import.',
+ 'job_config_input' => 'Your input',
+ // job configuration for the fake provider:
+ 'job_config_fake_artist_title' => 'Enter album name',
+ 'job_config_fake_artist_text' => 'Many import routines have a few configuration steps you must go through. In the case of the fake import provider, you must answer some weird questions. In this case, enter "David Bowie" to continue.',
+ 'job_config_fake_song_title' => 'Enter song name',
+ 'job_config_fake_song_text' => 'Mention the song "Golden years" to continue with the fake import.',
+ 'job_config_fake_album_title' => 'Enter album name',
+ 'job_config_fake_album_text' => 'Some import routines require extra data halfway through the import. In the case of the fake import provider, you must answer some weird questions. Enter "Station to station" to continue.',
+ // job configuration form the file provider
+ 'job_config_file_upload_title' => 'Import setup (1/4) - Upload your file',
+ 'job_config_file_upload_text' => 'This routine will help you import files from your bank into Firefly III. ',
+ 'job_config_file_upload_help' => 'Select your file. Please make sure the file is UTF-8 encoded.',
+ 'job_config_file_upload_config_help' => 'If you have previously imported data into Firefly III, you may have a configuration file, which will pre-set configuration values for you. For some banks, other users have kindly provided their configuration file',
+ 'job_config_file_upload_type_help' => 'Select the type of file you will upload',
+ 'job_config_file_upload_submit' => 'Upload files',
+ 'import_file_type_csv' => 'CSV (valeurs séparées par des virgules)',
+ 'file_not_utf8' => 'The file you have uploaded is not encoded as UTF-8 or ASCII. Firefly III cannot handle such files. Please use Notepad++ or Sublime to convert your file to UTF-8.',
+ 'job_config_uc_title' => 'Import setup (2/4) - Basic file setup',
+ 'job_config_uc_text' => 'To be able to import your file correctly, please validate the options below.',
+ 'job_config_uc_header_help' => 'Check this box if the first row of your CSV file are the column titles.',
+ 'job_config_uc_date_help' => 'Date time format in your file. Follow the format as this page indicates. The default value will parse dates that look like this: :dateExample.',
+ 'job_config_uc_delimiter_help' => 'Choose the field delimiter that is used in your input file. If not sure, comma is the safest option.',
+ 'job_config_uc_account_help' => 'If your file does NOT contain information about your asset account(s), use this dropdown to select to which account the transactions in the file belong to.',
+ 'job_config_uc_apply_rules_title' => 'Apply rules',
+ 'job_config_uc_apply_rules_text' => 'Applies your rules to every imported transaction. Note that this slows the import significantly.',
+ 'job_config_uc_specifics_title' => 'Bank-specific options',
+ 'job_config_uc_specifics_txt' => 'Some banks deliver badly formatted files. Firefly III can fix those automatically. If your bank delivers such files but it\'s not listed here, please open an issue on GitHub.',
+ 'job_config_uc_submit' => 'Continue',
+ 'invalid_import_account' => 'You have selected an invalid account to import into.',
+ // job configuration for Spectre:
+ 'job_config_spectre_login_title' => 'Choose your login',
+ 'job_config_spectre_login_text' => 'Firefly III has found :count existing login(s) in your Spectre account. Which one would you like to use to import from?',
+ 'spectre_login_status_active' => 'Active',
+ 'spectre_login_status_inactive' => 'Inactive',
+ 'spectre_login_status_disabled' => 'Disabled',
+ 'spectre_login_new_login' => 'Login with another bank, or one of these banks with different credentials.',
+ 'job_config_spectre_accounts_title' => 'Select accounts to import from',
+ 'job_config_spectre_accounts_text' => 'You have selected ":name" (:country). You have :count account(s) available from this provider. Please select the Firefly III asset account(s) where the transactions from these accounts should be stored. Remember, in order to import data both the Firefly III account and the ":name"-account must have the same currency.',
+ 'spectre_no_supported_accounts' => 'You cannot import from this account due to a currency mismatch.',
+ 'spectre_do_not_import' => '(do not import)',
+ 'spectre_no_mapping' => 'It seems you have not selected any accounts to import from.',
+ 'imported_from_account' => 'Imported from ":account"',
+ 'spectre_account_with_number' => 'Account :number',
+ // job configuration for bunq:
+ 'job_config_bunq_accounts_title' => 'bunq accounts',
+ 'job_config_bunq_accounts_text' => 'These are the accounts associated with your bunq account. Please select the accounts from which you want to import, and in which account the transactions must be imported.',
+ 'bunq_no_mapping' => 'It seems you have not selected any accounts.',
+ 'should_download_config' => 'You should download the configuration file for this job. This will make future imports way easier.',
+ 'share_config_file' => 'If you have imported data from a public bank, you should share your configuration file so it will be easy for other users to import their data. Sharing your configuration file will not expose your financial details.',
+
+ // keys from "extra" array:
+ 'spectre_extra_key_iban' => 'IBAN',
+ 'spectre_extra_key_swift' => 'SWIFT',
+ 'spectre_extra_key_status' => 'Status',
+ 'spectre_extra_key_card_type' => 'Card type',
+ 'spectre_extra_key_account_name' => 'Account name',
+ 'spectre_extra_key_client_name' => 'Client name',
+ 'spectre_extra_key_account_number' => 'Account number',
+ 'spectre_extra_key_blocked_amount' => 'Blocked amount',
+ 'spectre_extra_key_available_amount' => 'Available amount',
+ 'spectre_extra_key_credit_limit' => 'Credit limit',
+ 'spectre_extra_key_interest_rate' => 'Interest rate',
+ 'spectre_extra_key_expiry_date' => 'Expiry date',
+ 'spectre_extra_key_open_date' => 'Open date',
+ 'spectre_extra_key_current_time' => 'Current time',
+ 'spectre_extra_key_current_date' => 'Current date',
+ 'spectre_extra_key_cards' => 'Cards',
+ 'spectre_extra_key_units' => 'Units',
+ 'spectre_extra_key_unit_price' => 'Unit price',
+ 'spectre_extra_key_transactions_count' => 'Transaction count',
+
+ // specifics:
+ 'specific_ing_name' => 'ING NL',
+ 'specific_ing_descr' => 'Create better descriptions in ING exports',
+ 'specific_sns_name' => 'SNS / Volksbank NL',
+ 'specific_sns_descr' => 'Trim quotes from SNS / Volksbank export files',
+ 'specific_abn_name' => 'ABN AMRO NL',
+ 'specific_abn_descr' => 'Fixes potential problems with ABN AMRO files',
+ 'specific_rabo_name' => 'Rabobank NL',
+ 'specific_rabo_descr' => 'Fixes potential problems with Rabobank files',
+ 'specific_pres_name' => 'President\'s Choice Financial CA',
+ 'specific_pres_descr' => 'Fixes potential problems with PC files',
+ // job configuration for file provider (stage: roles)
+ 'job_config_roles_title' => 'Import setup (3/4) - Define each column\'s role',
+ 'job_config_roles_text' => 'Each column in your CSV file contains certain data. Please indicate what kind of data the importer should expect. The option to "map" data means that you will link each entry found in the column to a value in your database. An often mapped column is the column that contains the IBAN of the opposing account. That can be easily matched to IBAN\'s present in your database already.',
+ 'job_config_roles_submit' => 'Continue',
+ 'job_config_roles_column_name' => 'Name of column',
+ 'job_config_roles_column_example' => 'Column example data',
+ 'job_config_roles_column_role' => 'Column data meaning',
+ 'job_config_roles_do_map_value' => 'Map these values',
+ 'job_config_roles_no_example' => 'No example data available',
+ 'job_config_roles_fa_warning' => 'If you mark a column as containing an amount in a foreign currency, you must also set the column that contains which currency it is.',
+ 'job_config_roles_rwarning' => 'At the very least, mark one column as the amount-column. It is advisable to also select a column for the description, date and the opposing account.',
+ 'job_config_roles_colum_count' => 'Column',
+ // job config for the file provider (stage: mapping):
+ 'job_config_map_title' => 'Import setup (4/4) - Connect import data to Firefly III data',
+ 'job_config_map_text' => 'In the following tables, the left value shows you information found in your uploaded file. It is your task to map this value, if possible, to a value already present in your database. Firefly will stick to this mapping. If there is no value to map to, or you do not wish to map the specific value, select nothing.',
+ 'job_config_map_nothing' => 'There is no data present in your file that you can map to existing values. Please press "Start the import" to continue.',
+ 'job_config_field_value' => 'Field value',
+ 'job_config_field_mapped' => 'Mapped to',
+ 'map_do_not_map' => '(ne pas mapper)',
+ 'job_config_map_submit' => 'Start the import',
+
+
+ // import status page:
+ 'import_with_key' => 'Importer avec la clé \':key\'',
'status_wait_title' => 'Veuillez patienter...',
'status_wait_text' => 'Cette boîte disparaîtra dans un instant.',
- 'status_fatal_title' => 'Une erreur fatale est survenue',
- 'status_fatal_text' => 'Une erreur fatale est survenue que le traitement d\'importation ne peut pas récupérer. Voir l\'explication en rouge ci-dessous.',
- 'status_fatal_more' => 'Si l\'erreur est un time-out, l\'importation sera arrêtée pendant son traitement. Pour certaines configurations de serveur, ce n\'est que le serveur qui s\'est arrêté alors que l\'importation continue de fonctionner en arrière-plan. Pour vérifier cela, consultez les fichiers journaux. Si le problème persiste, envisagez d\'importer plutôt par ligne de commande.',
- 'status_ready_title' => 'L\'importation est prête à démarrer',
- 'status_ready_text' => 'L\'importation est prête à démarrer. Toute la configuration requise été effectuée. Vous pouvez téléchargez le fichier de configuration. Cela vous permettra de recommencer rapidement l\'importation si tout ne fonctionnait pas comme prévu. Pour exécuter l\'importation, vous pouvez soit exécuter la commande suivante dans la console du serveur, soit exécuter l\'importation depuis cette page web. Selon votre configuration générale, l\'importation via la console vous donnera plus de détails.',
- 'status_ready_noconfig_text' => 'L\'importation est prête à démarrer. Toute la configuration requise été effectuée. Pour exécuter l\'importation, vous pouvez soit exécuter la commande suivante dans la console du serveur, soit exécuter l\'importation depuis cette page web. Selon votre configuration générale, l\'importation via la console vous donnera plus de détails.',
- 'status_ready_config' => 'Télécharger la configuration',
- 'status_ready_start' => 'Démarrer l\'importation',
- 'status_ready_share' => 'Vous pouvez télécharger votre configuration et de la partager dans le centre de configuration d\'import. Cela permettra à d\'autres utilisateurs de Firefly III d\'importer leurs fichiers plus facilement.',
- 'status_job_new' => 'Le travail est tout récent.',
- 'status_job_configuring' => 'L\'importation est en cours de configuration.',
- 'status_job_configured' => 'L\'importation est configurée.',
- 'status_job_running' => 'L\'importation est en cours... Veuillez patienter...',
- 'status_job_error' => 'Le travail a généré une erreur.',
- 'status_job_finished' => 'L\'importation est terminée !',
'status_running_title' => 'L\'importation est en cours d\'exécution',
- 'status_running_placeholder' => 'Attendez pour une mise à jour...',
- 'status_finished_title' => 'Le traitement d\'importation est terminé',
- 'status_finished_text' => 'Le traitement d\'importation a importé vos données.',
- 'status_errors_title' => 'Erreurs lors de l\'importation',
- 'status_errors_single' => 'Une erreur est survenue lors de l\'importation. Cela ne semble pas être fatal.',
- 'status_errors_multi' => 'Certaines erreurs sont survenues lors de l\'importation. Celles-ci ne semblent pas être fatales.',
- 'status_bread_crumb' => 'Statut d\'importation',
- 'status_sub_title' => 'Statut d\'importation',
- 'config_sub_title' => 'Configurez votre importation',
- 'status_finished_job' => 'The :count transactions imported can be found in tag :tag.',
- 'status_finished_no_tag' => 'Firefly III has not collected any transactions from your import file.',
- 'import_with_key' => 'Importer avec la clé \':key\'',
+ 'status_job_running' => 'Please wait, running the import...',
+ 'status_job_storing' => 'Please wait, storing data...',
+ 'status_job_rules' => 'Please wait, running rules...',
+ 'status_fatal_title' => 'Fatal error',
+ 'status_fatal_text' => 'The import has suffered from an error it could not recover from. Apologies!',
+ 'status_fatal_more' => 'This (possibly very cryptic) error message is complemented by log files, which you can find on your hard drive, or in the Docker container where you run Firefly III from.',
+ 'status_finished_title' => 'Import finished',
+ 'status_finished_text' => 'The import has finished.',
+ 'finished_with_errors' => 'There were some errors during the import. Please review them carefully.',
+ 'unknown_import_result' => 'Unknown import result',
+ 'result_no_transactions' => 'No transactions have been imported. Perhaps they were all duplicates is simply no transactions where present to be imported. Perhaps the log files can tell you what happened. If you import data regularly, this is normal.',
+ 'result_one_transaction' => 'Exactly one transaction has been imported. It is stored under tag :tag where you can inspect it further.',
+ 'result_many_transactions' => 'Firefly III has imported :count transactions. They are stored under tag :tag where you can inspect them further.',
- // file, upload something
- 'file_upload_title' => 'Configuration de l\'importation (1/4) - Téléchargez votre fichier',
- 'file_upload_text' => 'Ce traitement vous aidera à importer des fichiers de votre banque dans Firefly III. Consultez les pages d\'aide en haut à droite.',
- 'file_upload_fields' => 'Champs',
- 'file_upload_help' => 'Sélectionnez votre fichier',
- 'file_upload_config_help' => 'Si vous avez précédemment importé des données dans Firefly III, vous avez peut-être téléchargé un fichier de configuration qui définit les relations entre les différents champs. Pour certaines banques, des utilisateurs ont bien voulu partager leur fichier ici : fichiers de configuration.',
- 'file_upload_type_help' => 'Sélectionnez le type de fichier que vous allez télécharger',
- 'file_upload_submit' => 'Envoyer des fichiers',
- // file, upload types
- 'import_file_type_csv' => 'CSV (valeurs séparées par des virgules)',
+ // general errors and warnings:
+ 'bad_job_status' => 'To access this page, your import job cannot have status ":status".',
- // file, initial config for CSV
- 'csv_initial_title' => 'Configuration d\'importation (2/4) - Configuration d\'importation CSV',
- 'csv_initial_text' => 'Pour pouvoir importer votre fichier correctement, veuillez valider les options ci-dessous.',
- 'csv_initial_box' => 'Configuration d\'importation CSV de base',
- 'csv_initial_box_title' => 'Options de configuration de l\'importation CSV de base',
- 'csv_initial_header_help' => 'Cochez cette case si la première ligne de votre fichier CSV contient les entêtes des colonnes.',
- 'csv_initial_date_help' => 'Date time format in your CSV. Follow the format like this page indicates. The default value will parse dates that look like this: :dateExample.',
- 'csv_initial_delimiter_help' => 'Choose the field delimiter that is used in your input file. If not sure, comma is the safest option.',
- 'csv_initial_import_account_help' => 'If your CSV file does NOT contain information about your asset account(s), use this dropdown to select to which account the transactions in the CSV belong to.',
- 'csv_initial_submit' => 'Passez à l’étape 3/4',
-
- // file, new options:
- 'file_apply_rules_title' => 'Appliquer les règles',
- 'file_apply_rules_description' => 'Apply your rules. Note that this slows the import significantly.',
- 'file_match_bills_title' => 'Faire correspondre les factures',
- 'file_match_bills_description' => 'Match your bills to newly created withdrawals. Note that this slows the import significantly.',
-
- // file, roles config
- 'csv_roles_title' => 'Import setup (3/4) - Define each column\'s role',
- 'csv_roles_text' => 'Each column in your CSV file contains certain data. Please indicate what kind of data the importer should expect. The option to "map" data means that you will link each entry found in the column to a value in your database. An often mapped column is the column that contains the IBAN of the opposing account. That can be easily matched to IBAN\'s present in your database already.',
- 'csv_roles_table' => 'Tableau',
- 'csv_roles_column_name' => 'Nom de colonne',
- 'csv_roles_column_example' => 'Données d\'exemple de colonne',
- 'csv_roles_column_role' => 'Signification des données de colonne',
- 'csv_roles_do_map_value' => 'Mapper ces valeurs',
- 'csv_roles_column' => 'Colonne',
- 'csv_roles_no_example_data' => 'Aucun exemple de données disponible',
- 'csv_roles_submit' => 'Passez à l’étape 4/4',
-
- // not csv, but normal warning
- 'roles_warning' => 'At the very least, mark one column as the amount-column. It is advisable to also select a column for the description, date and the opposing account.',
- 'foreign_amount_warning' => 'If you mark a column as containing an amount in a foreign currency, you must also set the column that contains which currency it is.',
-
- // file, map data
- 'file_map_title' => 'Import setup (4/4) - Connect import data to Firefly III data',
- 'file_map_text' => 'In the following tables, the left value shows you information found in your uploaded file. It is your task to map this value, if possible, to a value already present in your database. Firefly will stick to this mapping. If there is no value to map to, or you do not wish to map the specific value, select nothing.',
- 'file_map_field_value' => 'Valeur du champ',
- 'file_map_field_mapped_to' => 'Mappé à ',
- 'map_do_not_map' => '(ne pas mapper)',
- 'file_map_submit' => 'Démarrez l\'importation',
- 'file_nothing_to_map' => 'There is no data present in your file that you can map to existing values. Please press "Start the import" to continue.',
-
- // map things.
+ // column roles for CSV import:
'column__ignore' => '(ignorer cette colonne)',
'column_account-iban' => 'Compte d’actif (IBAN)',
'column_account-id' => 'Asset account ID (matching FF3)',
@@ -151,55 +254,11 @@ return [
'column_sepa-ci' => 'SEPA Creditor Identifier',
'column_sepa-ep' => 'SEPA External Purpose',
'column_sepa-country' => 'SEPA Country Code',
- 'column_tags-comma' => 'Tags (comma separated)',
- 'column_tags-space' => 'Tags (space separated)',
+ 'column_tags-comma' => 'Tags (séparés par des virgules)',
+ 'column_tags-space' => 'Tags (séparé par un espace)',
'column_account-number' => 'Asset account (account number)',
'column_opposing-number' => 'Opposing account (account number)',
'column_note' => 'Note(s)',
'column_internal-reference' => 'Internal reference',
- // prerequisites
- 'prerequisites' => 'Prerequisites',
-
- // bunq
- 'bunq_prerequisites_title' => 'Prerequisites for an import from bunq',
- 'bunq_prerequisites_text' => 'In order to import from bunq, you need to obtain an API key. You can do this through the app. Please note that the import function for bunq is in BETA. It has only been tested against the sandbox API.',
- 'bunq_prerequisites_text_ip' => 'Bunq requires your externally facing IP address. Firefly III has tried to fill this in using the ipify service. Make sure this IP address is correct, or the import will fail.',
- 'bunq_do_import' => 'Yes, import from this account',
- 'bunq_accounts_title' => 'Bunq accounts',
- 'bunq_accounts_text' => 'These are the accounts associated with your bunq account. Please select the accounts from which you want to import, and in which account the transactions must be imported.',
-
- // Spectre
- 'spectre_title' => 'Import using Spectre',
- 'spectre_prerequisites_title' => 'Prerequisites for an import using Spectre',
- 'spectre_prerequisites_text' => 'In order to import data using the Spectre API (v4), you must provide Firefly III with two secret values. They can be found on the secrets page.',
- 'spectre_enter_pub_key' => 'The import will only work when you enter this public key on your secrets page.',
- 'spectre_accounts_title' => 'Select accounts to import from',
- 'spectre_accounts_text' => 'Each account on the left below has been found by Spectre and can be imported into Firefly III. Please select the asset account that should hold any given transactions. If you do not wish to import from any particular account, remove the check from the checkbox.',
- 'spectre_do_import' => 'Yes, import from this account',
- 'spectre_no_supported_accounts' => 'You cannot import from this account due to a currency mismatch.',
-
- // keys from "extra" array:
- 'spectre_extra_key_iban' => 'IBAN',
- 'spectre_extra_key_swift' => 'SWIFT',
- 'spectre_extra_key_status' => 'Status',
- 'spectre_extra_key_card_type' => 'Card type',
- 'spectre_extra_key_account_name' => 'Account name',
- 'spectre_extra_key_client_name' => 'Client name',
- 'spectre_extra_key_account_number' => 'Account number',
- 'spectre_extra_key_blocked_amount' => 'Blocked amount',
- 'spectre_extra_key_available_amount' => 'Available amount',
- 'spectre_extra_key_credit_limit' => 'Credit limit',
- 'spectre_extra_key_interest_rate' => 'Interest rate',
- 'spectre_extra_key_expiry_date' => 'Expiry date',
- 'spectre_extra_key_open_date' => 'Open date',
- 'spectre_extra_key_current_time' => 'Current time',
- 'spectre_extra_key_current_date' => 'Current date',
- 'spectre_extra_key_cards' => 'Cards',
- 'spectre_extra_key_units' => 'Units',
- 'spectre_extra_key_unit_price' => 'Unit price',
- 'spectre_extra_key_transactions_count' => 'Transaction count',
-
- // various other strings:
- 'imported_from_account' => 'Imported from ":account"',
];
diff --git a/resources/lang/fr_FR/intro.php b/resources/lang/fr_FR/intro.php
index 2b4ed6d7fb..103c316b23 100644
--- a/resources/lang/fr_FR/intro.php
+++ b/resources/lang/fr_FR/intro.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
// index
'index_intro' => 'Bienvenue sur la page index de Firefly III. Veuillez prendre le temps de parcourir l\'introduction pour comprendre comment Firefly III fonctionne.',
diff --git a/resources/lang/fr_FR/list.php b/resources/lang/fr_FR/list.php
index 0001821206..ccafd1e385 100644
--- a/resources/lang/fr_FR/list.php
+++ b/resources/lang/fr_FR/list.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
'buttons' => 'Boutons',
'icon' => 'Icône',
@@ -111,10 +112,15 @@ return [
'sepa-cc' => 'Code de compensation SEPA',
'sepa-ep' => 'Objectif externe SEPA',
'sepa-ci' => 'Identifiant SEPA Creditor',
+ 'external_id' => 'External ID',
'account_at_bunq' => 'Compte avec bunq',
'file_name' => 'File name',
'file_size' => 'File size',
'file_type' => 'File type',
'attached_to' => 'Attached to',
'file_exists' => 'File exists',
+ 'spectre_bank' => 'Bank',
+ 'spectre_last_use' => 'Last login',
+ 'spectre_status' => 'Status',
+ 'bunq_payment_id' => 'bunq payment ID',
];
diff --git a/resources/lang/fr_FR/pagination.php b/resources/lang/fr_FR/pagination.php
index d58666a2e4..b07c1ca899 100644
--- a/resources/lang/fr_FR/pagination.php
+++ b/resources/lang/fr_FR/pagination.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
'previous' => '« Précédent',
'next' => 'Suivant »',
diff --git a/resources/lang/fr_FR/passwords.php b/resources/lang/fr_FR/passwords.php
index 7a6e781409..e8f757293f 100644
--- a/resources/lang/fr_FR/passwords.php
+++ b/resources/lang/fr_FR/passwords.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
'password' => 'Les mots de passe doivent contenir au moins six caractères et correspondre à la confirmation.',
'user' => 'Nous ne pouvons pas trouver d\'utilisateur avec cette adresse e-mail.',
diff --git a/resources/lang/fr_FR/validation.php b/resources/lang/fr_FR/validation.php
index 68e8799c02..6ce0d06474 100644
--- a/resources/lang/fr_FR/validation.php
+++ b/resources/lang/fr_FR/validation.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
'iban' => 'Il ne s\'agit pas d\'un IBAN valide.',
'source_equals_destination' => 'Le compte source est égal au compte de destination',
@@ -109,7 +110,8 @@ return [
'in_array' => 'Le champ :attribute n\'existe pas dans :other.',
'present' => 'Le champs :attribute doit être rempli.',
'amount_zero' => 'Le montant total ne peut pas être zéro',
- 'secure_password' => 'Ce n’est pas un mot de passe sécurisé. S’il vous plaît essayer de nouveau. Pour plus d’informations, visitez https://goo.gl/NCh2tN',
+ 'unique_piggy_bank_for_user' => 'The name of the piggy bank must be unique.',
+ 'secure_password' => 'This is not a secure password. Please try again. For more information, visit http://bit.ly/FF3-password-security',
'attributes' => [
'email' => 'adresse email',
'description' => 'description',
diff --git a/resources/lang/id_ID/auth.php b/resources/lang/id_ID/auth.php
index d5c89b1738..a0fabdfc2b 100644
--- a/resources/lang/id_ID/auth.php
+++ b/resources/lang/id_ID/auth.php
@@ -1,9 +1,8 @@
.
*/
-return [
- /*
- |--------------------------------------------------------------------------
- | Authentication Language Lines
- |--------------------------------------------------------------------------
- |
- | The following language lines are used during authentication for various
- | messages that we need to display to the user. You are free to modify
- | these language lines according to your application's requirements.
- |
- */
+declare(strict_types=1);
+return [
'failed' => 'Kredensial ini tidak sesuai dengan catatan kami.',
'throttle' => 'Terlalu banyak upaya login. Silakan coba lagi dalam :seconds detik.',
];
diff --git a/resources/lang/id_ID/bank.php b/resources/lang/id_ID/bank.php
index 8826020cbf..5d00b1e685 100644
--- a/resources/lang/id_ID/bank.php
+++ b/resources/lang/id_ID/bank.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
];
diff --git a/resources/lang/id_ID/breadcrumbs.php b/resources/lang/id_ID/breadcrumbs.php
index 37012db64f..a6e166fd57 100644
--- a/resources/lang/id_ID/breadcrumbs.php
+++ b/resources/lang/id_ID/breadcrumbs.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
'home' => 'Beranda',
'edit_currency' => 'Edit mata uang ":name"',
diff --git a/resources/lang/id_ID/components.php b/resources/lang/id_ID/components.php
index 50092e06fd..6299088f8e 100644
--- a/resources/lang/id_ID/components.php
+++ b/resources/lang/id_ID/components.php
@@ -1,5 +1,4 @@
.
*/
+declare(strict_types=1);
+
return [
// profile
'personal_access_tokens' => 'Personal access tokens',
diff --git a/resources/lang/id_ID/config.php b/resources/lang/id_ID/config.php
index 1d5d9e7592..64659774cd 100644
--- a/resources/lang/id_ID/config.php
+++ b/resources/lang/id_ID/config.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
'html_language' => 'id',
'locale' => 'id, Bahasa Indonesia, id_ID, id_ID.utf8, id_ID.UTF-8',
diff --git a/resources/lang/id_ID/csv.php b/resources/lang/id_ID/csv.php
index 622a49202a..aae109a40a 100644
--- a/resources/lang/id_ID/csv.php
+++ b/resources/lang/id_ID/csv.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
];
diff --git a/resources/lang/id_ID/demo.php b/resources/lang/id_ID/demo.php
index be9aeac6ac..a62c929dc0 100644
--- a/resources/lang/id_ID/demo.php
+++ b/resources/lang/id_ID/demo.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
'no_demo_text' => 'Maaf, tidak ada teks penjelasan-penjelasan tambahan laman halaman ini.',
'see_help_icon' => 'Namun, ikon di pojok kanan atas mungkin memberi tahu Anda lebih banyak.',
@@ -32,5 +33,5 @@ return [
'currencies-index' => 'Firefly III mendukung banyak mata uang. Meski default ke Euro itu bisa diatur ke US Dollar dan banyak mata uang lainnya. Seperti yang bisa Anda lihat, sejumlah kecil mata uang telah disertakan namun Anda dapat menambahkannya sendiri jika menginginkannya. Mengubah mata uang default tidak akan mengubah mata uang dari transaksi yang ada namun: Firefly III mendukung penggunaan beberapa mata uang pada saat bersamaan.',
'transactions-index' => 'Biaya ini, deposito dan transfer tidak terlalu imajinatif. Mereka telah dihasilkan secara otomatis.',
'piggy-banks-index' => 'Seperti yang bisa Anda lihat, ada tiga celengan. Gunakan tombol plus dan minus untuk mempengaruhi jumlah uang di setiap celengan. Klik nama celengan untuk melihat administrasi masing-masing celengan.',
- 'import-index' => 'Tentu saja, file CSV manapun bisa diimpor ke Firefly III',
+ 'import-index' => 'Any CSV file can be imported into Firefly III. It also supports importing data from bunq and Spectre. Other banks and financial aggregators will be implemented in the future. As a demo-user however, you can only see the "fake"-provider in action. It will generate some random transactions to show you how the process works.',
];
diff --git a/resources/lang/id_ID/firefly.php b/resources/lang/id_ID/firefly.php
index d831542d5d..348ed93b3a 100644
--- a/resources/lang/id_ID/firefly.php
+++ b/resources/lang/id_ID/firefly.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
// general stuff:
'close' => 'Dekat',
@@ -179,6 +180,7 @@ return [
'authorization_request_intro' => ':client is requesting permission to access your financial administration. Would you like to authorize :client to access these records?',
'scopes_will_be_able' => 'This application will be able to:',
'button_authorize' => 'Authorize',
+ 'none_in_select_list' => '(none)',
// check for updates:
'update_check_title' => 'Check for updates',
@@ -666,6 +668,7 @@ return [
'bill_will_automatch' => 'Tagihan akan secara otomatis terhubung ke transaksi yang sesuai',
'skips_over' => 'melompati',
'bill_store_error' => 'An unexpected error occurred while storing your new bill. Please check the log files',
+ 'list_inactive_rule' => 'inactive rule',
// accounts:
'details_for_asset' => 'Rincian akun aset ":name"',
@@ -801,6 +804,7 @@ return [
'opt_group_savingAsset' => 'Menyimpan akun',
'opt_group_sharedAsset' => 'Akun aset bersama',
'opt_group_ccAsset' => 'Kartu kredit',
+ 'opt_group_cashWalletAsset' => 'Cash wallets',
'notes' => 'Notes',
'unknown_journal_error' => 'Could not store the transaction. Please check the log files.',
@@ -816,6 +820,7 @@ return [
'language' => 'Language',
'new_savings_account' => ':bank_name savings account',
'cash_wallet' => 'Cash wallet',
+ 'currency_not_present' => 'If the currency you normally use is not listed do not worry. You can create your own currencies under Options > Currencies.',
// home page:
'yourAccounts' => 'Akun anda',
@@ -1013,6 +1018,7 @@ return [
'remove_money_from_piggy_title' => 'Hapus uang dari celengan ":name"',
'add' => 'Menambahkan',
'no_money_for_piggy' => 'Anda tidak punya uang untuk dimasukkan ke dalam celengan ini.',
+ 'suggested_savings_per_month' => 'Suggested per month',
'remove' => 'Menghapus',
'max_amount_add' => 'Jumlah maksimum yang bisa Anda tambahkan adalah',
@@ -1148,27 +1154,9 @@ return [
'no_edit_multiple_left' => 'Anda tidak memilih transaksi yang sah untuk diedit.',
'cannot_convert_split_journal' => 'Tidak dapat mengonversi transaksi split',
- // import bread crumbs and titles:
- 'import' => 'Impor',
- 'import_data' => 'Impor data',
- 'import_general_index_file' => 'Impor file',
- 'import_from_bunq' => 'Impor dari bunq',
- 'import_using_spectre' => 'Impor menggunakan momok',
- 'import_using_plaid' => 'Impor menggunakan Plaid',
- 'import_config_bread_crumb' => 'Siapkan impor Anda',
-
- // import index page:
+ // Import page (general strings only)
'import_index_title' => 'Impor data ke Firefly III',
- 'import_index_sub_title' => 'Indeks',
- 'import_general_index_intro' => 'Welcome to Firefly III\'s import routine. There are a few ways of importing data into Firefly III, displayed here as buttons.',
- 'upload_error' => 'The file you have uploaded could not be processed. Possibly it is of an invalid file type or encoding. The log files will have more information.',
- 'reset_import_settings_title' => 'Reset import configuration',
- 'reset_import_settings_text' => 'You can use these links to reset your import settings for specific providers. This is useful when bad settings stop you from importing data.',
- 'reset_settings_bunq' => 'Remove bunq API key, local external IP address and bunq related RSA keys.',
- 'reset_settings_spectre' => 'Remove Spectre secrets and ID\'s. This will also remove your Spectre keypair. Remember to update the new one.',
- 'settings_reset_for_bunq' => 'Bunq settings reset.',
- 'settings_reset_for_spectre' => 'Spectre settings reset.',
-
+ 'import_data' => 'Impor data',
// sandstorm.io errors and messages:
'sandstorm_not_available' => 'Fungsi ini tidak tersedia saat Anda menggunakan Firefly III di dalam lingkungan Sandstorm.io.',
diff --git a/resources/lang/id_ID/form.php b/resources/lang/id_ID/form.php
index 16431078e1..6dd307210f 100644
--- a/resources/lang/id_ID/form.php
+++ b/resources/lang/id_ID/form.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
// new user:
'bank_name' => 'Nama Bank',
@@ -184,6 +185,13 @@ return [
'blocked' => 'Apakah diblokir?',
'blocked_code' => 'Alasan untuk blok',
+ // import
+ 'apply_rules' => 'Apply rules',
+ 'artist' => 'Artist',
+ 'album' => 'Album',
+ 'song' => 'Song',
+
+
// admin
'domain' => 'Domain',
'single_user_mode' => 'Nonaktifkan pendaftaran pengguna',
diff --git a/resources/lang/id_ID/import.php b/resources/lang/id_ID/import.php
index a580259879..93809b1375 100644
--- a/resources/lang/id_ID/import.php
+++ b/resources/lang/id_ID/import.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
- // status of import:
+ // ALL breadcrumbs and subtitles:
+ 'index_breadcrumb' => 'Import data into Firefly III',
+ 'prerequisites_breadcrumb_fake' => 'Prerequisites for the fake import provider',
+ 'prerequisites_breadcrumb_spectre' => 'Prerequisites for Spectre',
+ 'prerequisites_breadcrumb_bunq' => 'Prerequisites for bunq',
+ 'job_configuration_breadcrumb' => 'Configuration for ":key"',
+ 'job_status_breadcrumb' => 'Import status for ":key"',
+ 'cannot_create_for_provider' => 'Firefly III cannot create a job for the ":provider"-provider.',
+
+ // index page:
+ 'general_index_title' => 'Import a file',
+ 'general_index_intro' => 'Welcome to Firefly III\'s import routine. There are a few ways of importing data into Firefly III, displayed here as buttons.',
+ // import provider strings (index):
+ 'button_fake' => 'Fake an import',
+ 'button_file' => 'Import a file',
+ 'button_bunq' => 'Import from bunq',
+ 'button_spectre' => 'Import using Spectre',
+ 'button_plaid' => 'Import using Plaid',
+ 'button_yodlee' => 'Import using Yodlee',
+ 'button_quovo' => 'Import using Quovo',
+ // global config box (index)
+ 'global_config_title' => 'Global import configuration',
+ 'global_config_text' => 'In the future, this box will feature preferences that apply to ALL import providers above.',
+ // prerequisites box (index)
+ 'need_prereq_title' => 'Import prerequisites',
+ 'need_prereq_intro' => 'Some import methods need your attention before they can be used. For example, they might require special API keys or application secrets. You can configure them here. The icon indicates if these prerequisites have been met.',
+ 'do_prereq_fake' => 'Prerequisites for the fake provider',
+ 'do_prereq_file' => 'Prerequisites for file imports',
+ 'do_prereq_bunq' => 'Prerequisites for imports from bunq',
+ 'do_prereq_spectre' => 'Prerequisites for imports using Spectre',
+ 'do_prereq_plaid' => 'Prerequisites for imports using Plaid',
+ 'do_prereq_yodlee' => 'Prerequisites for imports using Yodlee',
+ 'do_prereq_quovo' => 'Prerequisites for imports using Quovo',
+ // provider config box (index)
+ 'can_config_title' => 'Import configuration',
+ 'can_config_intro' => 'Some import methods can be configured to your liking. They have extra settings you can tweak.',
+ 'do_config_fake' => 'Configuration for the fake provider',
+ 'do_config_file' => 'Configuration for file imports',
+ 'do_config_bunq' => 'Configuration for bunq imports',
+ 'do_config_spectre' => 'Configuration for imports from Spectre',
+ 'do_config_plaid' => 'Configuration for imports from Plaid',
+ 'do_config_yodlee' => 'Configuration for imports from Yodlee',
+ 'do_config_quovo' => 'Configuration for imports from Quovo',
+
+ // prerequisites:
+ 'prereq_fake_title' => 'Prerequisites for an import from the fake import provider',
+ 'prereq_fake_text' => 'This fake provider requires a fake API key. It must be 32 characters long. You can use this one: 123456789012345678901234567890AA',
+ 'prereq_spectre_title' => 'Prerequisites for an import using the Spectre API',
+ 'prereq_spectre_text' => 'In order to import data using the Spectre API (v4), you must provide Firefly III with two secret values. They can be found on the secrets page.',
+ 'prereq_spectre_pub' => 'Likewise, the Spectre API needs to know the public key you see below. Without it, it will not recognize you. Please enter this public key on your secrets page.',
+ 'prereq_bunq_title' => 'Prerequisites for an import from bunq',
+ 'prereq_bunq_text' => 'In order to import from bunq, you need to obtain an API key. You can do this through the app. Please note that the import function for bunq is in BETA. It has only been tested against the sandbox API.',
+ 'prereq_bunq_ip' => 'bunq requires your externally facing IP address. Firefly III has tried to fill this in using the ipify service. Make sure this IP address is correct, or the import will fail.',
+ // prerequisites success messages:
+ 'prerequisites_saved_for_fake' => 'Fake API key stored successfully!',
+ 'prerequisites_saved_for_spectre' => 'App ID and secret stored!',
+ 'prerequisites_saved_for_bunq' => 'API key and IP stored!',
+
+ // job configuration:
+ 'job_config_apply_rules_title' => 'Job configuration - apply your rules?',
+ 'job_config_apply_rules_text' => 'Once the fake provider has run, your rules can be applied to the transactions. This adds time to the import.',
+ 'job_config_input' => 'Your input',
+ // job configuration for the fake provider:
+ 'job_config_fake_artist_title' => 'Enter album name',
+ 'job_config_fake_artist_text' => 'Many import routines have a few configuration steps you must go through. In the case of the fake import provider, you must answer some weird questions. In this case, enter "David Bowie" to continue.',
+ 'job_config_fake_song_title' => 'Enter song name',
+ 'job_config_fake_song_text' => 'Mention the song "Golden years" to continue with the fake import.',
+ 'job_config_fake_album_title' => 'Enter album name',
+ 'job_config_fake_album_text' => 'Some import routines require extra data halfway through the import. In the case of the fake import provider, you must answer some weird questions. Enter "Station to station" to continue.',
+ // job configuration form the file provider
+ 'job_config_file_upload_title' => 'Import setup (1/4) - Upload your file',
+ 'job_config_file_upload_text' => 'This routine will help you import files from your bank into Firefly III. ',
+ 'job_config_file_upload_help' => 'Select your file. Please make sure the file is UTF-8 encoded.',
+ 'job_config_file_upload_config_help' => 'If you have previously imported data into Firefly III, you may have a configuration file, which will pre-set configuration values for you. For some banks, other users have kindly provided their configuration file',
+ 'job_config_file_upload_type_help' => 'Select the type of file you will upload',
+ 'job_config_file_upload_submit' => 'Upload files',
+ 'import_file_type_csv' => 'CSV (nilai yang dipisahkan koma)',
+ 'file_not_utf8' => 'The file you have uploaded is not encoded as UTF-8 or ASCII. Firefly III cannot handle such files. Please use Notepad++ or Sublime to convert your file to UTF-8.',
+ 'job_config_uc_title' => 'Import setup (2/4) - Basic file setup',
+ 'job_config_uc_text' => 'To be able to import your file correctly, please validate the options below.',
+ 'job_config_uc_header_help' => 'Check this box if the first row of your CSV file are the column titles.',
+ 'job_config_uc_date_help' => 'Date time format in your file. Follow the format as this page indicates. The default value will parse dates that look like this: :dateExample.',
+ 'job_config_uc_delimiter_help' => 'Choose the field delimiter that is used in your input file. If not sure, comma is the safest option.',
+ 'job_config_uc_account_help' => 'If your file does NOT contain information about your asset account(s), use this dropdown to select to which account the transactions in the file belong to.',
+ 'job_config_uc_apply_rules_title' => 'Apply rules',
+ 'job_config_uc_apply_rules_text' => 'Applies your rules to every imported transaction. Note that this slows the import significantly.',
+ 'job_config_uc_specifics_title' => 'Bank-specific options',
+ 'job_config_uc_specifics_txt' => 'Some banks deliver badly formatted files. Firefly III can fix those automatically. If your bank delivers such files but it\'s not listed here, please open an issue on GitHub.',
+ 'job_config_uc_submit' => 'Continue',
+ 'invalid_import_account' => 'You have selected an invalid account to import into.',
+ // job configuration for Spectre:
+ 'job_config_spectre_login_title' => 'Choose your login',
+ 'job_config_spectre_login_text' => 'Firefly III has found :count existing login(s) in your Spectre account. Which one would you like to use to import from?',
+ 'spectre_login_status_active' => 'Active',
+ 'spectre_login_status_inactive' => 'Inactive',
+ 'spectre_login_status_disabled' => 'Disabled',
+ 'spectre_login_new_login' => 'Login with another bank, or one of these banks with different credentials.',
+ 'job_config_spectre_accounts_title' => 'Select accounts to import from',
+ 'job_config_spectre_accounts_text' => 'You have selected ":name" (:country). You have :count account(s) available from this provider. Please select the Firefly III asset account(s) where the transactions from these accounts should be stored. Remember, in order to import data both the Firefly III account and the ":name"-account must have the same currency.',
+ 'spectre_no_supported_accounts' => 'You cannot import from this account due to a currency mismatch.',
+ 'spectre_do_not_import' => '(do not import)',
+ 'spectre_no_mapping' => 'It seems you have not selected any accounts to import from.',
+ 'imported_from_account' => 'Imported from ":account"',
+ 'spectre_account_with_number' => 'Account :number',
+ // job configuration for bunq:
+ 'job_config_bunq_accounts_title' => 'bunq accounts',
+ 'job_config_bunq_accounts_text' => 'These are the accounts associated with your bunq account. Please select the accounts from which you want to import, and in which account the transactions must be imported.',
+ 'bunq_no_mapping' => 'It seems you have not selected any accounts.',
+ 'should_download_config' => 'You should download the configuration file for this job. This will make future imports way easier.',
+ 'share_config_file' => 'If you have imported data from a public bank, you should share your configuration file so it will be easy for other users to import their data. Sharing your configuration file will not expose your financial details.',
+
+ // keys from "extra" array:
+ 'spectre_extra_key_iban' => 'IBAN',
+ 'spectre_extra_key_swift' => 'SWIFT',
+ 'spectre_extra_key_status' => 'Status',
+ 'spectre_extra_key_card_type' => 'Card type',
+ 'spectre_extra_key_account_name' => 'Account name',
+ 'spectre_extra_key_client_name' => 'Client name',
+ 'spectre_extra_key_account_number' => 'Account number',
+ 'spectre_extra_key_blocked_amount' => 'Blocked amount',
+ 'spectre_extra_key_available_amount' => 'Available amount',
+ 'spectre_extra_key_credit_limit' => 'Credit limit',
+ 'spectre_extra_key_interest_rate' => 'Interest rate',
+ 'spectre_extra_key_expiry_date' => 'Expiry date',
+ 'spectre_extra_key_open_date' => 'Open date',
+ 'spectre_extra_key_current_time' => 'Current time',
+ 'spectre_extra_key_current_date' => 'Current date',
+ 'spectre_extra_key_cards' => 'Cards',
+ 'spectre_extra_key_units' => 'Units',
+ 'spectre_extra_key_unit_price' => 'Unit price',
+ 'spectre_extra_key_transactions_count' => 'Transaction count',
+
+ // specifics:
+ 'specific_ing_name' => 'ING NL',
+ 'specific_ing_descr' => 'Create better descriptions in ING exports',
+ 'specific_sns_name' => 'SNS / Volksbank NL',
+ 'specific_sns_descr' => 'Trim quotes from SNS / Volksbank export files',
+ 'specific_abn_name' => 'ABN AMRO NL',
+ 'specific_abn_descr' => 'Fixes potential problems with ABN AMRO files',
+ 'specific_rabo_name' => 'Rabobank NL',
+ 'specific_rabo_descr' => 'Fixes potential problems with Rabobank files',
+ 'specific_pres_name' => 'President\'s Choice Financial CA',
+ 'specific_pres_descr' => 'Fixes potential problems with PC files',
+ // job configuration for file provider (stage: roles)
+ 'job_config_roles_title' => 'Import setup (3/4) - Define each column\'s role',
+ 'job_config_roles_text' => 'Each column in your CSV file contains certain data. Please indicate what kind of data the importer should expect. The option to "map" data means that you will link each entry found in the column to a value in your database. An often mapped column is the column that contains the IBAN of the opposing account. That can be easily matched to IBAN\'s present in your database already.',
+ 'job_config_roles_submit' => 'Continue',
+ 'job_config_roles_column_name' => 'Name of column',
+ 'job_config_roles_column_example' => 'Column example data',
+ 'job_config_roles_column_role' => 'Column data meaning',
+ 'job_config_roles_do_map_value' => 'Map these values',
+ 'job_config_roles_no_example' => 'No example data available',
+ 'job_config_roles_fa_warning' => 'If you mark a column as containing an amount in a foreign currency, you must also set the column that contains which currency it is.',
+ 'job_config_roles_rwarning' => 'At the very least, mark one column as the amount-column. It is advisable to also select a column for the description, date and the opposing account.',
+ 'job_config_roles_colum_count' => 'Column',
+ // job config for the file provider (stage: mapping):
+ 'job_config_map_title' => 'Import setup (4/4) - Connect import data to Firefly III data',
+ 'job_config_map_text' => 'In the following tables, the left value shows you information found in your uploaded file. It is your task to map this value, if possible, to a value already present in your database. Firefly will stick to this mapping. If there is no value to map to, or you do not wish to map the specific value, select nothing.',
+ 'job_config_map_nothing' => 'There is no data present in your file that you can map to existing values. Please press "Start the import" to continue.',
+ 'job_config_field_value' => 'Field value',
+ 'job_config_field_mapped' => 'Mapped to',
+ 'map_do_not_map' => '(jangan memetakan)',
+ 'job_config_map_submit' => 'Start the import',
+
+
+ // import status page:
+ 'import_with_key' => 'Impor dengan kunci \':key\'',
'status_wait_title' => 'Tolong tunggu sebentar...',
'status_wait_text' => 'Kotak ini akan hilang dalam sekejap.',
- 'status_fatal_title' => 'Sebuah kesalahan fatal terjadi',
- 'status_fatal_text' => 'Kesalahan fatal terjadi, dimana rutinitas impor tidak dapat dipulihkan. Silakan lihat penjelasannya di bawah ini.',
- 'status_fatal_more' => 'Jika kesalahannya adalah time-out, impor akan berhenti setengah jalan. Untuk beberapa konfigurasi server, hanya server yang berhenti sementara impor terus berjalan di latar belakang. Untuk memverifikasi ini, periksa file log. Jika masalah berlanjut, pertimbangkan untuk mengimpor lebih dari baris perintah.',
- 'status_ready_title' => 'Impor sudah siap untuk memulai',
- 'status_ready_text' => 'Impor sudah siap dimulai. Semua konfigurasi yang perlu Anda lakukan sudah selesai. Silahkan download file konfigurasi. Ini akan membantu Anda dengan impor seandainya tidak berjalan seperti yang direncanakan. Untuk benar-benar menjalankan impor, Anda dapat menjalankan perintah berikut di konsol Anda, atau menjalankan impor berbasis web. Bergantung pada konfigurasi Anda, impor konsol akan memberi Anda lebih banyak umpan balik.',
- 'status_ready_noconfig_text' => 'Impor sudah siap dimulai. Semua konfigurasi yang perlu Anda lakukan sudah selesai. Untuk benar-benar menjalankan impor, Anda dapat menjalankan perintah berikut di konsol Anda, atau menjalankan impor berbasis web. Bergantung pada konfigurasi Anda, impor konsol akan memberi Anda lebih banyak umpan balik.',
- 'status_ready_config' => 'Download konfigurasi',
- 'status_ready_start' => 'Mulai impor',
- 'status_ready_share' => 'Harap pertimbangkan untuk mendownload konfigurasi Anda dan membagikannya di pusat konfigurasi impor. Ini akan memungkinkan pengguna Firefly III lainnya untuk mengimpor file mereka dengan lebih mudah.',
- 'status_job_new' => 'Pekerjaan itu baru.',
- 'status_job_configuring' => 'Impor sedang dikonfigurasi.',
- 'status_job_configured' => 'Impor dikonfigurasi.',
- 'status_job_running' => 'Impor sedang berjalan.. mohon menunggu..',
- 'status_job_error' => 'Pekerjaan telah menimbulkan kesalahan.',
- 'status_job_finished' => 'Impor telah selesai!',
'status_running_title' => 'Impor sedang berjalan',
- 'status_running_placeholder' => 'Silakan tunggu update...',
- 'status_finished_title' => 'Rutin impor selesai',
- 'status_finished_text' => 'Rutin impor telah mengimpor data Anda.',
- 'status_errors_title' => 'Kesalahan selama impor',
- 'status_errors_single' => 'Terjadi kesalahan saat mengimpor. Itu tidak tampak berakibat fatal.',
- 'status_errors_multi' => 'Beberapa kesalahan terjadi saat impor. Ini tidak tampak berakibat fatal.',
- 'status_bread_crumb' => 'Status impor',
- 'status_sub_title' => 'Status impor',
- 'config_sub_title' => 'Siapkan impor Anda',
- 'status_finished_job' => 'The :count transactions imported can be found in tag :tag.',
- 'status_finished_no_tag' => 'Firefly III has not collected any transactions from your import file.',
- 'import_with_key' => 'Impor dengan kunci \':key\'',
+ 'status_job_running' => 'Please wait, running the import...',
+ 'status_job_storing' => 'Please wait, storing data...',
+ 'status_job_rules' => 'Please wait, running rules...',
+ 'status_fatal_title' => 'Fatal error',
+ 'status_fatal_text' => 'The import has suffered from an error it could not recover from. Apologies!',
+ 'status_fatal_more' => 'This (possibly very cryptic) error message is complemented by log files, which you can find on your hard drive, or in the Docker container where you run Firefly III from.',
+ 'status_finished_title' => 'Import finished',
+ 'status_finished_text' => 'The import has finished.',
+ 'finished_with_errors' => 'There were some errors during the import. Please review them carefully.',
+ 'unknown_import_result' => 'Unknown import result',
+ 'result_no_transactions' => 'No transactions have been imported. Perhaps they were all duplicates is simply no transactions where present to be imported. Perhaps the log files can tell you what happened. If you import data regularly, this is normal.',
+ 'result_one_transaction' => 'Exactly one transaction has been imported. It is stored under tag :tag where you can inspect it further.',
+ 'result_many_transactions' => 'Firefly III has imported :count transactions. They are stored under tag :tag where you can inspect them further.',
- // file, upload something
- 'file_upload_title' => 'Impor setup (1/4) - Upload file Anda',
- 'file_upload_text' => 'Rutin ini akan membantu Anda mengimpor file dari bank Anda ke Firefly III. Silakan periksa halaman bantuan di pojok kanan atas.',
- 'file_upload_fields' => 'Bidang',
- 'file_upload_help' => 'Pilih file anda',
- 'file_upload_config_help' => 'Jika sebelumnya Anda mengimpor data ke Firefly III, Anda mungkin memiliki file konfigurasi, yang akan menetapkan nilai konfigurasi untuk Anda. Untuk beberapa bank, pengguna lain dengan ramah memberikan berkas konfigurasi mereka',
- 'file_upload_type_help' => 'Pilih jenis file yang akan anda upload',
- 'file_upload_submit' => 'Unggah berkas',
- // file, upload types
- 'import_file_type_csv' => 'CSV (nilai yang dipisahkan koma)',
+ // general errors and warnings:
+ 'bad_job_status' => 'To access this page, your import job cannot have status ":status".',
- // file, initial config for CSV
- 'csv_initial_title' => 'Penyiapan impor (2/4) - Penyiapan impor CSV dasar',
- 'csv_initial_text' => 'Untuk dapat mengimpor file Anda dengan benar, mohon validasi pilihan di bawah ini.',
- 'csv_initial_box' => 'Penyiapan impor CSV dasar',
- 'csv_initial_box_title' => 'Opsi penyiapan impor CSV dasar',
- 'csv_initial_header_help' => 'Centang kotak ini jika baris pertama file CSV Anda adalah judul kolom.',
- 'csv_initial_date_help' => 'Format waktu tanggal di CSV Anda. Ikuti format seperti laman ini menunjukkan. Nilai default akan mengurai tanggal yang terlihat seperti ini: :dateExample.',
- 'csv_initial_delimiter_help' => 'Pilih pembatas lapangan yang digunakan dalam file masukan Anda. Jika tidak yakin, koma adalah pilihan teraman.',
- 'csv_initial_import_account_help' => 'Jika file CSV TIDAK berisi informasi tentang akun aset Anda, gunakan dropdown ini untuk memilih akun mana yang menjadi tempat transaksi di CSV.',
- 'csv_initial_submit' => 'Lanjutkan dengan langkah 3/4',
-
- // file, new options:
- 'file_apply_rules_title' => 'Terapkan aturan',
- 'file_apply_rules_description' => 'Terapkan peraturan Anda Perhatikan bahwa ini memperlambat impor secara signifikan.',
- 'file_match_bills_title' => 'Cocokkan tagihan',
- 'file_match_bills_description' => 'Cocokkan tagihan Anda dengan penarikan yang baru dibuat. Perhatikan bahwa ini memperlambat impor secara signifikan.',
-
- // file, roles config
- 'csv_roles_title' => 'Pengaturan impor (3/4) - Tentukan peran masing-masing kolom',
- 'csv_roles_text' => 'Setiap kolom dalam file CSV Anda berisi data tertentu. Tolong tunjukkan jenis data yang harus diharapkan oleh importir. Pilihan untuk "memetakan" data berarti Anda akan menghubungkan setiap entri yang ditemukan di kolom ke nilai di database Anda. Kolom yang sering dipetakan adalah kolom yang berisi IBAN dari akun lawan. Itu bisa dengan mudah disesuaikan dengan keberadaan IBAN di database Anda.',
- 'csv_roles_table' => 'Meja',
- 'csv_roles_column_name' => 'Nama kolom',
- 'csv_roles_column_example' => 'Kolom contoh data',
- 'csv_roles_column_role' => 'Data kolom berarti',
- 'csv_roles_do_map_value' => 'Peta nilai-nilai ini',
- 'csv_roles_column' => 'Kolom',
- 'csv_roles_no_example_data' => 'Tidak ada data contoh yang tersedia',
- 'csv_roles_submit' => 'Lanjutkan dengan langkah 4/4',
-
- // not csv, but normal warning
- 'roles_warning' => 'At the very least, mark one column as the amount-column. It is advisable to also select a column for the description, date and the opposing account.',
- 'foreign_amount_warning' => 'If you mark a column as containing an amount in a foreign currency, you must also set the column that contains which currency it is.',
-
- // file, map data
- 'file_map_title' => 'Pengaturan impor (4/4) - Sambungkan data impor ke data Firefly III',
- 'file_map_text' => 'Pada tabel berikut, nilai kiri menunjukkan informasi yang Anda temukan di file yang Anda upload. Adalah tugas Anda untuk memetakan nilai ini, jika mungkin, ke nilai yang sudah ada di database Anda. Firefly akan menempel pada pemetaan ini. Jika tidak ada nilai untuk dipetakan, atau Anda tidak ingin memetakan nilai spesifiknya, pilih yang tidak ada.',
- 'file_map_field_value' => 'Nilai lapangan',
- 'file_map_field_mapped_to' => 'Dipetakan ke',
- 'map_do_not_map' => '(jangan memetakan)',
- 'file_map_submit' => 'Mulai impor',
- 'file_nothing_to_map' => 'There is no data present in your file that you can map to existing values. Please press "Start the import" to continue.',
-
- // map things.
+ // column roles for CSV import:
'column__ignore' => '(abaikan kolom ini)',
'column_account-iban' => 'Akun aset (IBAN)',
'column_account-id' => 'Asset account ID (matching FF3)',
@@ -158,48 +261,4 @@ return [
'column_note' => 'Catatan (s)',
'column_internal-reference' => 'Internal reference',
- // prerequisites
- 'prerequisites' => 'Prerequisites',
-
- // bunq
- 'bunq_prerequisites_title' => 'Prasyarat untuk impor dari bunq',
- 'bunq_prerequisites_text' => 'In order to import from bunq, you need to obtain an API key. You can do this through the app. Please note that the import function for bunq is in BETA. It has only been tested against the sandbox API.',
- 'bunq_prerequisites_text_ip' => 'Bunq requires your externally facing IP address. Firefly III has tried to fill this in using the ipify service. Make sure this IP address is correct, or the import will fail.',
- 'bunq_do_import' => 'Yes, import from this account',
- 'bunq_accounts_title' => 'Bunq accounts',
- 'bunq_accounts_text' => 'These are the accounts associated with your bunq account. Please select the accounts from which you want to import, and in which account the transactions must be imported.',
-
- // Spectre
- 'spectre_title' => 'Impor menggunakan momok',
- 'spectre_prerequisites_title' => 'Prasyarat untuk impor menggunakan momok',
- 'spectre_prerequisites_text' => 'In order to import data using the Spectre API (v4), you must provide Firefly III with two secret values. They can be found on the secrets page.',
- 'spectre_enter_pub_key' => 'The import will only work when you enter this public key on your secrets page.',
- 'spectre_accounts_title' => 'Select accounts to import from',
- 'spectre_accounts_text' => 'Each account on the left below has been found by Spectre and can be imported into Firefly III. Please select the asset account that should hold any given transactions. If you do not wish to import from any particular account, remove the check from the checkbox.',
- 'spectre_do_import' => 'Yes, import from this account',
- 'spectre_no_supported_accounts' => 'You cannot import from this account due to a currency mismatch.',
-
- // keys from "extra" array:
- 'spectre_extra_key_iban' => 'IBAN',
- 'spectre_extra_key_swift' => 'SWIFT',
- 'spectre_extra_key_status' => 'Status',
- 'spectre_extra_key_card_type' => 'Card type',
- 'spectre_extra_key_account_name' => 'Account name',
- 'spectre_extra_key_client_name' => 'Client name',
- 'spectre_extra_key_account_number' => 'Account number',
- 'spectre_extra_key_blocked_amount' => 'Blocked amount',
- 'spectre_extra_key_available_amount' => 'Available amount',
- 'spectre_extra_key_credit_limit' => 'Credit limit',
- 'spectre_extra_key_interest_rate' => 'Interest rate',
- 'spectre_extra_key_expiry_date' => 'Expiry date',
- 'spectre_extra_key_open_date' => 'Open date',
- 'spectre_extra_key_current_time' => 'Current time',
- 'spectre_extra_key_current_date' => 'Current date',
- 'spectre_extra_key_cards' => 'Cards',
- 'spectre_extra_key_units' => 'Units',
- 'spectre_extra_key_unit_price' => 'Unit price',
- 'spectre_extra_key_transactions_count' => 'Transaction count',
-
- // various other strings:
- 'imported_from_account' => 'Imported from ":account"',
];
diff --git a/resources/lang/id_ID/intro.php b/resources/lang/id_ID/intro.php
index 2c47c0c340..393970564b 100644
--- a/resources/lang/id_ID/intro.php
+++ b/resources/lang/id_ID/intro.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
// index
'index_intro' => 'Selamat datang di halaman indeks Firefly III. Mohon luangkan waktu untuk menelusuri pengantar ini melihat bagaimana Firefly III bekerja.',
diff --git a/resources/lang/id_ID/list.php b/resources/lang/id_ID/list.php
index ea8d946364..d64698938c 100644
--- a/resources/lang/id_ID/list.php
+++ b/resources/lang/id_ID/list.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
'buttons' => 'Tombol',
'icon' => 'Ikon',
@@ -111,10 +112,15 @@ return [
'sepa-cc' => 'SEPA Clearing Code',
'sepa-ep' => 'SEPA External Purpose',
'sepa-ci' => 'SEPA Creditor Identifier',
+ 'external_id' => 'External ID',
'account_at_bunq' => 'Account with bunq',
'file_name' => 'File name',
'file_size' => 'File size',
'file_type' => 'File type',
'attached_to' => 'Attached to',
'file_exists' => 'File exists',
+ 'spectre_bank' => 'Bank',
+ 'spectre_last_use' => 'Last login',
+ 'spectre_status' => 'Status',
+ 'bunq_payment_id' => 'bunq payment ID',
];
diff --git a/resources/lang/id_ID/pagination.php b/resources/lang/id_ID/pagination.php
index 0ec6186091..b581a04610 100644
--- a/resources/lang/id_ID/pagination.php
+++ b/resources/lang/id_ID/pagination.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
'previous' => '« Sebelumnya',
'next' => 'Selanjutnya »',
diff --git a/resources/lang/id_ID/passwords.php b/resources/lang/id_ID/passwords.php
index 766e5ac204..0081716690 100644
--- a/resources/lang/id_ID/passwords.php
+++ b/resources/lang/id_ID/passwords.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
'password' => 'Sandi minimal harus 6 karakter dan cocok dengan konfirmasi.',
'user' => 'Kami tidak dapat menemukan pengguna dengan alamat e-mail itu.',
diff --git a/resources/lang/id_ID/validation.php b/resources/lang/id_ID/validation.php
index ec4bcd3a77..00be6153a5 100644
--- a/resources/lang/id_ID/validation.php
+++ b/resources/lang/id_ID/validation.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
'iban' => 'Ini bukan IBAN yang valid.',
'source_equals_destination' => 'The source account equals the destination account',
@@ -109,7 +110,8 @@ return [
'in_array' => 'Bidang :attribute tidak ada in :other.',
'present' => 'Bidang :attribute harus ada.',
'amount_zero' => 'Jumlah total tidak boleh nol',
- 'secure_password' => 'Ini bukan kata sandi yang aman. Silahkan coba lagi. Untuk informasi lebih lanjut, kunjungi https://goo.gl/NCh2tN',
+ 'unique_piggy_bank_for_user' => 'The name of the piggy bank must be unique.',
+ 'secure_password' => 'This is not a secure password. Please try again. For more information, visit http://bit.ly/FF3-password-security',
'attributes' => [
'email' => 'email address',
'description' => 'description',
diff --git a/resources/lang/it_IT/auth.php b/resources/lang/it_IT/auth.php
index bcde25e00a..c3bc250669 100644
--- a/resources/lang/it_IT/auth.php
+++ b/resources/lang/it_IT/auth.php
@@ -1,9 +1,8 @@
.
*/
-return [
- /*
- |--------------------------------------------------------------------------
- | Authentication Language Lines
- |--------------------------------------------------------------------------
- |
- | The following language lines are used during authentication for various
- | messages that we need to display to the user. You are free to modify
- | these language lines according to your application's requirements.
- |
- */
+declare(strict_types=1);
+return [
'failed' => 'Queste credenziali non corrispondono ai nostri record.',
'throttle' => 'Troppi tentativi di accesso. Per favore riprova tra :seconds secondi.',
];
diff --git a/resources/lang/it_IT/bank.php b/resources/lang/it_IT/bank.php
index 8826020cbf..5d00b1e685 100644
--- a/resources/lang/it_IT/bank.php
+++ b/resources/lang/it_IT/bank.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
];
diff --git a/resources/lang/it_IT/breadcrumbs.php b/resources/lang/it_IT/breadcrumbs.php
index 92ae5d3c73..f631ee70e8 100644
--- a/resources/lang/it_IT/breadcrumbs.php
+++ b/resources/lang/it_IT/breadcrumbs.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
'home' => 'Home',
'edit_currency' => 'Modifica valuta ":name"',
@@ -38,7 +39,7 @@ return [
'reports' => 'Resoconti',
'search_result' => 'Risultati di ricerca per ":query"',
'withdrawal_list' => 'Spese',
- 'deposit_list' => 'Entrate, entrate e depositi',
+ 'deposit_list' => 'Reddito, entrate e depositi',
'transfer_list' => 'Trasferimenti',
'transfers_list' => 'Trasferimenti',
'reconciliation_list' => 'Riconciliazioni',
diff --git a/resources/lang/it_IT/components.php b/resources/lang/it_IT/components.php
index 82f04fce8f..296fa36c83 100644
--- a/resources/lang/it_IT/components.php
+++ b/resources/lang/it_IT/components.php
@@ -1,5 +1,4 @@
.
*/
+declare(strict_types=1);
+
return [
// profile
'personal_access_tokens' => 'Token di accesso personale',
diff --git a/resources/lang/it_IT/config.php b/resources/lang/it_IT/config.php
index acac8fc155..667e347c13 100644
--- a/resources/lang/it_IT/config.php
+++ b/resources/lang/it_IT/config.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
'html_language' => 'it',
'locale' => 'it, Italiano, it_IT, it_IT.utf8, it_IT.UTF-8',
diff --git a/resources/lang/it_IT/csv.php b/resources/lang/it_IT/csv.php
index 622a49202a..aae109a40a 100644
--- a/resources/lang/it_IT/csv.php
+++ b/resources/lang/it_IT/csv.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
];
diff --git a/resources/lang/it_IT/demo.php b/resources/lang/it_IT/demo.php
index e17fd3e782..38c210d8fb 100644
--- a/resources/lang/it_IT/demo.php
+++ b/resources/lang/it_IT/demo.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
'no_demo_text' => 'Spiacenti, non esiste un testo dimostrativo aggiuntivo per questa pagina.',
- 'see_help_icon' => 'Tuttavia, il -icon in alto a destra potrebbe dirti di più.',
+ 'see_help_icon' => 'Tuttavia, l\'icona i> in alto a destra potrebbe dirti di più.',
'index' => 'Benvenuto in Firefly III! In questa pagina ottieni una rapida panoramica delle tue finanze. Per ulteriori informazioni, controlla Account e → Account asset e, naturalmente, i budget e i resoconti. O semplicemente dai un\'occhiata in giro e vedi dove finisci.',
'accounts-index' => 'I conti degli asset sono i tuoi conti bancari personali. I conti spese sono gli account a cui si spendono soldi, come negozi e amici. I conti delle entrate sono conti da cui ricevi denaro, come il tuo lavoro, il governo o altre fonti di reddito. In questa pagina puoi modificarli o rimuoverli.',
'budgets-index' => 'Questa pagina ti mostra una panoramica dei tuoi budget. La barra in alto mostra l\'importo disponibile per essere preventivato. Questo può essere personalizzato per qualsiasi periodo facendo clic sull\'importo a destra. La quantità che hai effettivamente speso è mostrata nella barra sottostante. Di seguito sono indicate le spese per budget e ciò che hai preventivato per loro.',
@@ -32,5 +33,5 @@ return [
'currencies-index' => 'Firefly III supporta più valute. Sebbene sia impostato su Euro, può essere impostato sul dollaro USA e su molte altre valute. Come puoi vedere, è stata inclusa una piccola selezione di valute, ma puoi aggiungere la tua se lo desideri. Tuttavia, la modifica della valuta predefinita non cambierà la valuta delle transazioni esistenti: Firefly III supporta un uso di più valute allo stesso tempo.',
'transactions-index' => 'Queste spese, depositi e trasferimenti non sono particolarmente fantasiosi. Sono stati generati automaticamente.',
'piggy-banks-index' => 'Come puoi vedere, ci sono tre salvadanai. Utilizzare i pulsanti più e meno per influenzare la quantità di denaro in ogni salvadanaio. Fare clic sul nome del salvadanaio per visualizzare la gestione per ciascun salvadanaio.',
- 'import-index' => 'Naturalmente, qualsiasi file CSV può essere importato in Firefly III',
+ 'import-index' => 'Qualsiasi file CSV può essere importato in Firefly III. Supporta anche l\'importazione di dati da bunq e Spectre. Altre banche e aggregatori finanziari saranno implementati in futuro. Tuttavia, come utente demo, puoi vedere solo il provider "fittizio" in azione. Genererà alcune transazioni casuali per mostrarti come funziona il processo.',
];
diff --git a/resources/lang/it_IT/firefly.php b/resources/lang/it_IT/firefly.php
index 1ecb20c803..0532dcd126 100644
--- a/resources/lang/it_IT/firefly.php
+++ b/resources/lang/it_IT/firefly.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
// general stuff:
'close' => 'Chiudi',
@@ -44,7 +45,7 @@ return [
'asset_account_role_help' => 'Qualsiasi opzione aggiuntiva risultante dalla tua scelta può essere impostata in seguito.',
'Opening balance' => 'Saldo di apertura',
'create_new_stuff' => 'Crea nuove cose',
- 'new_withdrawal' => 'Nuova uscita',
+ 'new_withdrawal' => 'Nuovo prelievo',
'create_new_transaction' => 'Crea nuova transazione',
'go_to_asset_accounts' => 'Visualizza i tuoi movimenti',
'go_to_budgets' => 'Vai ai tuoi budget',
@@ -54,8 +55,8 @@ return [
'go_to_revenue_accounts' => 'Vedi i tuoi conti entrate',
'go_to_piggies' => 'Vai ai tuoi salvadanai',
'new_deposit' => 'Nuova entrata',
- 'new_transfer' => 'Nuovo giroconto',
- 'new_transfers' => 'Nuovi giroconti',
+ 'new_transfer' => 'Nuovo trasferimento',
+ 'new_transfers' => 'Nuovo trasferimento',
'new_asset_account' => 'Nuova attività conto',
'new_expense_account' => 'Nuova spesa conto',
'new_revenue_account' => 'Nuova entrata conto',
@@ -117,9 +118,9 @@ return [
'chart_account_in_period' => 'Grafico di tutte le transazioni per Conto ":name" fra :start E :end',
'chart_category_in_period' => 'Grafico di tutte le transazioni per Categorie ":name" fra :start e :end',
'chart_category_all' => 'Grafico di tutte le transazioni per Categoria ":name"',
- 'clone_withdrawal' => 'Duplica questo uscita',
+ 'clone_withdrawal' => 'Duplica questo prelievo',
'clone_deposit' => 'Duplica questa entrata',
- 'clone_transfer' => 'Duplica questo giroconto',
+ 'clone_transfer' => 'Duplica questo trasferimento',
'multi_select_no_selection' => 'Nessuno selezionato',
'multi_select_select_all' => 'Seleziona tutto',
'multi_select_n_selected' => 'selezionato',
@@ -179,6 +180,7 @@ return [
'authorization_request_intro' => ':client sta richiedendo l\'autorizzazione per accedere alla tua amministrazione finanziaria. Desideri autorizzare :client ad accedere a questi record?',
'scopes_will_be_able' => 'Questa applicazione sarà in grado di:',
'button_authorize' => 'Autorizza',
+ 'none_in_select_list' => '(nessuna)',
// check for updates:
'update_check_title' => 'Controlla aggiornamenti',
@@ -284,9 +286,9 @@ return [
'default_rule_trigger_from_account' => 'David Bowie',
'default_rule_action_prepend' => 'Comprato il mondo da ',
'default_rule_action_set_category' => 'Grandi spese',
- 'trigger' => 'Attivare',
- 'trigger_value' => 'Attiva il valore',
- 'stop_processing_other_triggers' => 'Interrompe l\'elaborazione di altre attivazioni',
+ 'trigger' => 'Trigger',
+ 'trigger_value' => 'Attiva al valore',
+ 'stop_processing_other_triggers' => 'Interrompi l\'elaborazione di altri trigger',
'add_rule_trigger' => 'Aggiungi un nuovo trigger',
'action' => 'Azione',
'action_value' => 'Valore azione',
@@ -310,25 +312,25 @@ return [
// actions and triggers
'rule_trigger_user_action' => 'L\'azione dell\'utente è ":trigger_value"',
- 'rule_trigger_from_account_starts_choice' => 'Il conto di origine inizia con..',
+ 'rule_trigger_from_account_starts_choice' => 'Il conto di origine inizia con...',
'rule_trigger_from_account_starts' => 'Il conto di origine inizia con ":trigger_value"',
- 'rule_trigger_from_account_ends_choice' => 'Il conto di origine termina con..',
+ 'rule_trigger_from_account_ends_choice' => 'Il conto di origine termina con...',
'rule_trigger_from_account_ends' => 'Il conto di origine termina con ":trigger_value"',
- 'rule_trigger_from_account_is_choice' => 'L\'account di origine è..',
- 'rule_trigger_from_account_is' => 'L\'account di origine è ":trigger_value"',
- 'rule_trigger_from_account_contains_choice' => 'Il conto di origine contiene..',
+ 'rule_trigger_from_account_is_choice' => 'Il conto di origine è...',
+ 'rule_trigger_from_account_is' => 'Il conto di origine è ":trigger_value"',
+ 'rule_trigger_from_account_contains_choice' => 'Il conto di origine contiene...',
'rule_trigger_from_account_contains' => 'Il conto di origine contiene ":trigger_value"',
- 'rule_trigger_to_account_starts_choice' => 'Il conto di destinazione inizia con..',
+ 'rule_trigger_to_account_starts_choice' => 'Il conto di destinazione inizia con...',
'rule_trigger_to_account_starts' => 'Il conto di destinazione inizia con ":trigger_value"',
- 'rule_trigger_to_account_ends_choice' => 'Il conto di destinazione termina con..',
+ 'rule_trigger_to_account_ends_choice' => 'Il conto di destinazione termina con...',
'rule_trigger_to_account_ends' => 'Il conto di destinazione termina con ":trigger_value"',
- 'rule_trigger_to_account_is_choice' => 'Il conto di destinazione è..',
+ 'rule_trigger_to_account_is_choice' => 'Il conto di destinazione è...',
'rule_trigger_to_account_is' => 'Il conto di destinazione è ":trigger_value"',
- 'rule_trigger_to_account_contains_choice' => 'Il conto di destinazione contiene..',
+ 'rule_trigger_to_account_contains_choice' => 'Il conto di destinazione contiene...',
'rule_trigger_to_account_contains' => 'Il conto di destinazione contiene ":trigger_value"',
- 'rule_trigger_transaction_type_choice' => 'La transazione è di tipo..',
+ 'rule_trigger_transaction_type_choice' => 'La transazione è di tipo...',
'rule_trigger_transaction_type' => 'La transazione è di tipo ":trigger_value"',
- 'rule_trigger_category_is_choice' => 'La categoria è..',
+ 'rule_trigger_category_is_choice' => 'La categoria è...',
'rule_trigger_category_is' => 'La categoria è ":trigger_value"',
'rule_trigger_amount_less_choice' => 'L\'importo è inferiore a..',
'rule_trigger_amount_less' => 'L\'importo è inferiore a :trigger_value',
@@ -347,7 +349,7 @@ return [
'rule_trigger_budget_is_choice' => 'Il budget è...',
'rule_trigger_budget_is' => 'Il budget è ":trigger_value"',
'rule_trigger_tag_is_choice' => '(A) tag è..',
- 'rule_trigger_tag_is' => 'Un tag è ":trigger_value"',
+ 'rule_trigger_tag_is' => 'Una etichetta è ":trigger_value"',
'rule_trigger_currency_is_choice' => 'La valuta della transazione è...',
'rule_trigger_currency_is' => 'La valuta della transazione è ":trigger_value"',
'rule_trigger_has_attachments_choice' => 'Ha almeno questo molti allegati',
@@ -360,8 +362,8 @@ return [
'rule_trigger_has_any_category' => 'La transazione ha una (qualsiasi) categoria',
'rule_trigger_has_no_budget_choice' => 'Non ha un budget',
'rule_trigger_has_no_budget' => 'La transazione non ha un budget',
- 'rule_trigger_has_any_budget_choice' => 'Ha un budget (qualsiasi)',
- 'rule_trigger_has_any_budget' => 'La transazione ha un budget (qualsiasi)',
+ 'rule_trigger_has_any_budget_choice' => 'Ha un (qualsiasi) budget',
+ 'rule_trigger_has_any_budget' => 'La transazione ha un (qualsiasi) budget',
'rule_trigger_has_no_tag_choice' => 'Non ha etichetta(e)',
'rule_trigger_has_no_tag' => 'La transazione non ha etichetta(e)',
'rule_trigger_has_any_tag_choice' => 'Ha una o più etichette (qualsiasi)',
@@ -420,7 +422,7 @@ return [
'rule_for_bill_title' => 'Regole generata automaticamente per la bolletta ":name"',
'rule_for_bill_description' => 'Questa regola è generata automaticamente per l\'abbinamento con la bolletta ":name".',
'create_rule_for_bill' => 'Crea una nuova regola per la bolletta ":name"',
- 'create_rule_for_bill_txt' => 'Contratulazioni, hai appena creato una nuova bolletta chiamata ":name"! Firefly III può automagicamente abbinare le nuove uscite a questa bolletta. Per esempio, ogni volta che paghi l\'affitto la bolletta "affitto" verrà collegata a questa spesa. In questo modo Firefly III può visualizzare con accuratezza quali bollette sono in scadenza e quali no. Per far ciò è necessario creare una nuova regola. Firefly III ha inserito al posto tuo alcuni dettagli ragionevoli. Assicurati che questi siano corretti. Se questi valori sono corretti, Firefly III automaticamente collegherà la spesa giusta alla bolletta giusta. Controlla che i trigger siano corretti e aggiungene altri se sono sbagliati.',
+ 'create_rule_for_bill_txt' => 'Contratulazioni, hai appena creato una nuova bolletta chiamata ":name"! Firefly III può automagicamente abbinare le nuove uscite a questa bolletta. Per esempio, ogni volta che paghi l\'affitto la bolletta "affitto" verrà collegata a questa spesa. In questo modo Firefly III può visualizzare con accuratezza quali bollette sono in scadenza e quali no. Per far ciò è necessario creare una nuova regola. Firefly III ha inserito al posto tuo alcuni dettagli ragionevoli. Assicurati che questi siano corretti. Se questi valori sono corretti, Firefly III automaticamente collegherà il prelievo giusto alla bolletta giusta. Controlla che i trigger siano corretti e aggiungene altri se sono sbagliati.',
'new_rule_for_bill_title' => 'Regola per la bolletta ":name"',
'new_rule_for_bill_description' => 'Questa regola contrassegna le transazioni per la bolletta ":name".',
@@ -541,7 +543,7 @@ return [
'attachment_deleted' => 'Allegato eliminato ":name"',
'attachment_updated' => 'Allegato aggiornato ":name"',
'upload_max_file_size' => 'Dimensione massima del file: :size',
- 'list_all_attachments' => 'List of all attachments',
+ 'list_all_attachments' => 'Lista di tutti gli allegati',
// transaction index
'title_expenses' => 'Spese',
@@ -554,42 +556,42 @@ return [
// convert stuff:
'convert_is_already_type_Withdrawal' => 'Questa transazione è già un prelievo',
'convert_is_already_type_Deposit' => 'Questa transazione è già un deposito',
- 'convert_is_already_type_Transfer' => 'Questa transazione è già un giroconto',
+ 'convert_is_already_type_Transfer' => 'Questa transazione è già un trasferimento',
'convert_to_Withdrawal' => 'Converti ":description" in un prelievo',
'convert_to_Deposit' => 'Converti ":description" in un deposito',
- 'convert_to_Transfer' => 'Converti ":description" in un giroconto',
- 'convert_options_WithdrawalDeposit' => 'Convertire un prelievo in un deposito',
- 'convert_options_WithdrawalTransfer' => 'Convertire un prelievo in un giroconto',
- 'convert_options_DepositTransfer' => 'Convertire un deposito in un giroconto',
+ 'convert_to_Transfer' => 'Converti ":description" in un trasferimento',
+ 'convert_options_WithdrawalDeposit' => 'Converti un prelievo in un deposito',
+ 'convert_options_WithdrawalTransfer' => 'Converti un prelievo in un trasferimento',
+ 'convert_options_DepositTransfer' => 'Converti un deposito in un trasferimento',
'convert_options_DepositWithdrawal' => 'Converti un deposito in un prelievo',
- 'convert_options_TransferWithdrawal' => 'Convertire un giroconto in un prelievo',
+ 'convert_options_TransferWithdrawal' => 'Converti un trasferimento in un prelievo',
'convert_options_TransferDeposit' => 'Converti un bonifico in un deposito',
'convert_Withdrawal_to_deposit' => 'Converti questo prelievo in un deposito',
- 'convert_Withdrawal_to_transfer' => 'Converti questo prelievo in un giroconto',
+ 'convert_Withdrawal_to_transfer' => 'Converti questo prelievo in un trasferimento',
'convert_Deposit_to_withdrawal' => 'Converti questo deposito in un prelievo',
- 'convert_Deposit_to_transfer' => 'Converti questo deposito in un giroconto',
- 'convert_Transfer_to_deposit' => 'Converti questo giroconto in un deposito',
- 'convert_Transfer_to_withdrawal' => 'Converti questo giroconto in un prelievo',
+ 'convert_Deposit_to_transfer' => 'Converti questo deposito in un trasferimento',
+ 'convert_Transfer_to_deposit' => 'Converti questo trasferimento in un deposito',
+ 'convert_Transfer_to_withdrawal' => 'Converti questo trasferimento in un prelievo',
'convert_please_set_revenue_source' => 'Si prega di scegliere il conto delle entrate da dove verranno i soldi.',
'convert_please_set_asset_destination' => 'Si prega di scegliere il conto patrimoniale dove andranno i soldi.',
'convert_please_set_expense_destination' => 'Si prega di scegliere il conto spese dove andranno i soldi.',
'convert_please_set_asset_source' => 'Si prega di scegliere il conto patrimoniale da dove verranno i soldi.',
'convert_explanation_withdrawal_deposit' => 'Se converti questo prelievo in un deposito, l\'importo verrà :amount depositato in :sourceName anziché prelevato da esso.',
- 'convert_explanation_withdrawal_transfer' => 'Se converti questo prelievo in un giroconto, l\'importo verrà :amount trasferito da :sourceName a un nuovo conto attività , invece di essere pagato a :destinationName.',
+ 'convert_explanation_withdrawal_transfer' => 'Se converti questo prelievo in un trasferimento, l\'importo verrà :amount trasferito da :sourceName a un nuovo conto attività , invece di essere pagato a :destinationName.',
'convert_explanation_deposit_withdrawal' => 'Se converti questo deposito in un prelievo, l\'importo verrà rimosso :amount da :destinationName anziché aggiunto ad esso.',
- 'convert_explanation_deposit_transfer' => 'Se converti questo deposito in un giroconto, :amount verrà trasferito da un conto attivo di tua scelta in :destinationName.',
- 'convert_explanation_transfer_withdrawal' => 'Se converti questo giroconto in un prelievo, l\'importo :amount andrà da :sourceName a una nuova destinazione a titolo di spesa, anziché a :destinationName come giroconto.',
- 'convert_explanation_transfer_deposit' => 'Se converti questo giroconto in un deposito, :amount verrà depositato nell\'account :destinationName anziché essere trasferito lì.',
+ 'convert_explanation_deposit_transfer' => 'Se converti questo deposito in un trasferimento, :amount verrà trasferito da un conto attivo di tua scelta in :destinationName.',
+ 'convert_explanation_transfer_withdrawal' => 'Se converti questo trasferimento in un prelievo, l\'importo :amount andrà da :sourceName a una nuova destinazione a titolo di spesa, anziché a :destinationName come trasferimento.',
+ 'convert_explanation_transfer_deposit' => 'Se converti questo trasferimento in un deposito, :amount verrà depositato nell\'account :destinationName anziché essere trasferito lì.',
'converted_to_Withdrawal' => 'La transazione è stata convertita in un prelievo',
'converted_to_Deposit' => 'La transazione è stata convertita in un deposito',
- 'converted_to_Transfer' => 'La transazione è stata convertita in un giroconto',
+ 'converted_to_Transfer' => 'La transazione è stata convertita in un trasferimento',
'invalid_convert_selection' => 'Tl\'account che hai selezionato è già utilizzato in questa transazione o non esiste.',
'source_or_dest_invalid' => 'Impossibile trovare i dettagli corretti della transazione. Non è possibile effettuare la conversione.',
// create new stuff:
'create_new_withdrawal' => 'Crea un nuovo prelievo',
'create_new_deposit' => 'Crea una nuova entrata',
- 'create_new_transfer' => 'Crea nuovo giroconto',
+ 'create_new_transfer' => 'Crea nuovo trasferimento',
'create_new_asset' => 'Crea un nuovo conto attività ',
'create_new_expense' => 'Crea un nuovo conto di spesa',
'create_new_revenue' => 'Crea un nuovo conto di entrate',
@@ -666,6 +668,7 @@ return [
'bill_will_automatch' => 'La bolletta verrà automaticamente collegata alle transazioni corrispondenti',
'skips_over' => 'salta sopra',
'bill_store_error' => 'Si è verificato un errore imprevisto durante la memorizzazione della nuova bolletta. Controlla i file di log',
+ 'list_inactive_rule' => 'regola inattiva',
// accounts:
'details_for_asset' => 'Dettagli per conto attività ":name"',
@@ -765,16 +768,16 @@ return [
// transactions:
'update_withdrawal' => 'Aggiorna spesa',
'update_deposit' => 'Aggiorna entrata',
- 'update_transfer' => 'Aggiorna giroconto',
+ 'update_transfer' => 'Aggiorna trasferimento',
'updated_withdrawal' => 'Spesa aggiornata ":description"',
'updated_deposit' => 'Entrata aggiornata ":description"',
- 'updated_transfer' => 'Giroconto aggiornato ":description"',
+ 'updated_transfer' => 'Trasferimento ":description" aggiornato',
'delete_withdrawal' => 'Elimina spesa ":description"',
'delete_deposit' => 'Elimina entrata ":description"',
- 'delete_transfer' => 'Elimina giroconto ":description"',
+ 'delete_transfer' => 'Elimina trasferimento ":description"',
'deleted_withdrawal' => 'Spesa eliminata correttamente ":description"',
'deleted_deposit' => 'Entrata eliminata correttamente ":description"',
- 'deleted_transfer' => 'Giroconto eliminato correttamente ":description"',
+ 'deleted_transfer' => 'Trasferimento ":description" eliminato correttamente',
'stored_journal' => 'Nuova transazione creata correttamente ":description"',
'select_transactions' => 'Seleziona transazioni',
'rule_group_select_transactions' => 'Applica ":title" a transazioni',
@@ -801,6 +804,7 @@ return [
'opt_group_savingAsset' => 'Conti risparmio',
'opt_group_sharedAsset' => 'Conti risorse condivise',
'opt_group_ccAsset' => 'Carte di credito',
+ 'opt_group_cashWalletAsset' => 'Contanti',
'notes' => 'Note',
'unknown_journal_error' => 'Impossibile memorizzare la transazione. Controllare i file di log.',
@@ -816,6 +820,7 @@ return [
'language' => 'Lingua',
'new_savings_account' => 'Conto di risparmio :bank_name',
'cash_wallet' => 'Contanti',
+ 'currency_not_present' => 'If the currency you normally use is not listed do not worry. You can create your own currencies under Options > Currencies.',
// home page:
'yourAccounts' => 'I tuoi conti',
@@ -823,7 +828,7 @@ return [
'savings' => 'Risparmi',
'newWithdrawal' => 'Nuova uscita',
'newDeposit' => 'Nuovo deposito',
- 'newTransfer' => 'Nuovo giroconto',
+ 'newTransfer' => 'Nuovo trasferimento',
'bills_to_pay' => 'Bollette da pagare',
'per_day' => 'Al giorno',
'left_to_spend_per_day' => 'Spese al giorno',
@@ -858,10 +863,10 @@ return [
'opening_balance' => 'Saldo di apertura',
'deposit' => 'Entrata',
'account' => 'Conto',
- 'transfer' => 'Giroconto',
+ 'transfer' => 'Trasferimento',
'Withdrawal' => 'Spesa',
'Deposit' => 'Entrata',
- 'Transfer' => 'Giroconto',
+ 'Transfer' => 'Trasferimento',
'bill' => 'Bolletta',
'yes' => 'Si',
'no' => 'No',
@@ -1013,6 +1018,7 @@ return [
'remove_money_from_piggy_title' => 'Rimuovi i soldi dal salvadanaio ":name"',
'add' => 'Aggiungi',
'no_money_for_piggy' => 'non hai soldi da mettere in questo salvadanaio.',
+ 'suggested_savings_per_month' => 'Suggested per month',
'remove' => 'Rimuovi',
'max_amount_add' => 'L\'importo massimo che puoi aggiungere è',
@@ -1083,7 +1089,7 @@ return [
'send_test_email' => 'Invia un messaggio di posta elettronica di prova',
'send_test_email_text' => 'Per vedere se la tua installazione è in grado di inviare e-mail, ti preghiamo di premere questo pulsante. Qui non vedrai un errore (se presente), i file di log rifletteranno eventuali errori. Puoi premere questo pulsante tutte le volte che vuoi. Non c\'è controllo dello spam. Il messaggio verrà inviato a :email e dovrebbe arrivare a breve.',
'send_message' => 'Invia messaggio',
- 'send_test_triggered' => 'Il test è stato attivato. Controlla la tua casella di posta e i file di registro.',
+ 'send_test_triggered' => 'Il test è stato attivato. Controlla la tua casella di posta e i file di log.',
// links
'journal_link_configuration' => 'Configurazione dei collegamenti di transazione',
@@ -1115,7 +1121,7 @@ return [
'journal_links' => 'Collegamenti di transazione',
'this_withdrawal' => 'Questa spesa',
'this_deposit' => 'Questa entrata',
- 'this_transfer' => 'Questo giroconto',
+ 'this_transfer' => 'Questo trasferimento',
'overview_for_link' => 'Panoramica per tipo di collegamento ":name"',
'source_transaction' => 'Transazione di origine',
'link_description' => 'Descrizione del collegamento',
@@ -1140,7 +1146,7 @@ return [
'do_split' => 'Fai una divisione',
'split_this_withdrawal' => 'Dividi questa spesa',
'split_this_deposit' => 'Dividi questa entrata',
- 'split_this_transfer' => 'Dividi questo giroconto',
+ 'split_this_transfer' => 'Dividi questo trasferimento',
'cannot_edit_multiple_source' => 'Non è possibile modificare la transazione n. #:id con la descrizione ":description" perché contiene più conti di origine.',
'cannot_edit_multiple_dest' => 'Non è possibile modificare la transazione n. #:id con la descrizione ":description" perché contiene più conti di destinazione.',
'cannot_edit_reconciled' => 'Non è possibile modificare la transazione n. #:id con la descrizione ":description" perché è stata contrassegnata come riconciliata.',
@@ -1148,27 +1154,9 @@ return [
'no_edit_multiple_left' => 'Non hai selezionato transazioni valide da modificare.',
'cannot_convert_split_journal' => 'Impossibile convertire una transazione divisa',
- // import bread crumbs and titles:
- 'import' => 'Importa',
- 'import_data' => 'Importa i dati',
- 'import_general_index_file' => 'Importa un file',
- 'import_from_bunq' => 'Importare dal bunq',
- 'import_using_spectre' => 'Importa usando Spettro',
- 'import_using_plaid' => 'Importa usando Plaid',
- 'import_config_bread_crumb' => 'Configura la tua importazione',
-
- // import index page:
+ // Import page (general strings only)
'import_index_title' => 'Importa i dati in Firefly III',
- 'import_index_sub_title' => 'Indice',
- 'import_general_index_intro' => 'Benvenuti nella routine di importazione di Firefly III. Esistono alcuni modi per importare dati in Firefly III, visualizzati qui come pulsanti.',
- 'upload_error' => 'Il file che hai caricato non può essere elaborato. Probabilmente è un tipo di file o una codifica non valida. I file di log avranno maggiori informazioni.',
- 'reset_import_settings_title' => 'Reimposta la configurazione di importazione',
- 'reset_import_settings_text' => 'Puoi utilizzare questi collegamenti per ripristinare le impostazioni di importazione per specifici fornitori. Ciò è utile quando delle impostazioni errate impediscono l\'importazione dei dati.',
- 'reset_settings_bunq' => 'Rimuovi la chiave API di bunq, l\'indirizzo IP locale esterno e le chiavi RSA correlate a bunq.',
- 'reset_settings_spectre' => 'Rimuovi i segreti e gli ID di Spectre. Questo rimuoverà anche la tua coppia di chiavi di Spectre. Ricordati di aggiornare quella nuova.',
- 'settings_reset_for_bunq' => 'Ripristina impostazioni bunq.',
- 'settings_reset_for_spectre' => 'Ripristina impostazioni Spectre.',
-
+ 'import_data' => 'Importa i dati',
// sandstorm.io errors and messages:
'sandstorm_not_available' => 'Questa funzione non è disponibile quando si utilizza Firefly III in un ambiente Sandstorm.io.',
@@ -1206,10 +1194,10 @@ return [
'no_transactions_intro_deposit' => 'non hai ancora entrate registrate. È necessario creare voci di reddito per iniziare a gestire le tue finanze.',
'no_transactions_imperative_deposit' => 'Hai ricevuto dei soldi? Dovresti scriverlo:',
'no_transactions_create_deposit' => 'Crea una entrata',
- 'no_transactions_title_transfers' => 'Creiamo un giroconto!',
- 'no_transactions_intro_transfers' => 'Non hai ancora giroconti. Quando sposti denaro tra i conti attività , viene registrato come giroconto.',
+ 'no_transactions_title_transfers' => 'Creiamo un trasferimento!',
+ 'no_transactions_intro_transfers' => 'Non hai ancora trasferimenti. Quando sposti denaro tra i conti attività , viene registrato come trasferimento.',
'no_transactions_imperative_transfers' => 'Hai spostato dei soldi in giro? Dovresti scriverlo:',
- 'no_transactions_create_transfers' => 'Crea un giroconto',
+ 'no_transactions_create_transfers' => 'Crea un trasferimento',
'no_piggies_title_default' => 'Creiamo un salvadanaio!',
'no_piggies_intro_default' => 'Non hai ancora salvadanai. Puoi creare salvadanai per dividere i tuoi risparmi e tenere traccia di ciò per cui stai risparmiando.',
'no_piggies_imperative_default' => 'Hai cose per le quali stai risparmiando? Crea un salvadanaio e tieni traccia:',
diff --git a/resources/lang/it_IT/form.php b/resources/lang/it_IT/form.php
index bf73d83fa4..2c47c1601f 100644
--- a/resources/lang/it_IT/form.php
+++ b/resources/lang/it_IT/form.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
// new user:
'bank_name' => 'Nome banca',
@@ -91,7 +92,7 @@ return [
'type' => 'Tipo',
'convert_Withdrawal' => 'Converti spesa',
'convert_Deposit' => 'Converti entrata',
- 'convert_Transfer' => 'Converti giroconto',
+ 'convert_Transfer' => 'Converti trasferimento',
'amount' => 'Importo',
'foreign_amount' => 'Importo estero',
@@ -184,6 +185,13 @@ return [
'blocked' => 'È bloccato?',
'blocked_code' => 'Motivo del blocco',
+ // import
+ 'apply_rules' => 'Applica regole',
+ 'artist' => 'Artista',
+ 'album' => 'Album',
+ 'song' => 'Brano',
+
+
// admin
'domain' => 'Dominio',
'single_user_mode' => 'Disabilita registrazione utente',
@@ -202,8 +210,8 @@ return [
'client_id' => 'ID Client',
'service_secret' => 'Servizio segreto',
'app_secret' => 'App segreto',
- 'app_id' => 'App ID',
- 'secret' => 'Secret',
+ 'app_id' => 'ID dell\'app',
+ 'secret' => 'Segreto',
'public_key' => 'Chiave Pubblica',
'country_code' => 'Codice Nazione',
'provider_code' => 'Banca o fornitore di dati',
diff --git a/resources/lang/it_IT/import.php b/resources/lang/it_IT/import.php
index 7b0b61a277..d91182b40d 100644
--- a/resources/lang/it_IT/import.php
+++ b/resources/lang/it_IT/import.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
- // status of import:
+ // ALL breadcrumbs and subtitles:
+ 'index_breadcrumb' => 'Importa i dati in Firefly III',
+ 'prerequisites_breadcrumb_fake' => 'Prerequisiti per il fornitore di importazione fittizio',
+ 'prerequisites_breadcrumb_spectre' => 'Prerequisiti per Spectre',
+ 'prerequisites_breadcrumb_bunq' => 'Prerequisiti per bunq',
+ 'job_configuration_breadcrumb' => 'Configurazione per ":key"',
+ 'job_status_breadcrumb' => 'Stato di importazione per ":key"',
+ 'cannot_create_for_provider' => 'Firefly III non può creare un lavoro per il provider ":provider".',
+
+ // index page:
+ 'general_index_title' => 'Importa un file',
+ 'general_index_intro' => 'Benvenuti nella routine di importazione di Firefly III. Esistono alcuni modi per importare dati in Firefly III, visualizzati qui come pulsanti.',
+ // import provider strings (index):
+ 'button_fake' => 'Esegui un\'importazione fittizia',
+ 'button_file' => 'Importa un file',
+ 'button_bunq' => 'Importa da bunq',
+ 'button_spectre' => 'Importa usando Spectre',
+ 'button_plaid' => 'Importa usando Plaid',
+ 'button_yodlee' => 'Importa usando Yodlee',
+ 'button_quovo' => 'Importa usando Quovo',
+ // global config box (index)
+ 'global_config_title' => 'Configurazione globale di importazione',
+ 'global_config_text' => 'In futuro, questo riquadro presenterà le preferenze che si applicano a TUTTI i fornitori di importazione di cui sopra.',
+ // prerequisites box (index)
+ 'need_prereq_title' => 'Prerequisiti di importazione',
+ 'need_prereq_intro' => 'Alcuni metodi di importazione richiedono la tua attenzione prima che possano essere utilizzati. Ad esempio, potrebbero richiedere speciali chiavi API o segreti dell\'applicazione. Puoi configurarli qui. L\'icona indica se questi prerequisiti sono stati soddisfatti.',
+ 'do_prereq_fake' => 'Prerequisiti per il fornitore fittizio',
+ 'do_prereq_file' => 'Prerequisiti per le importazioni da file',
+ 'do_prereq_bunq' => 'Prerequisiti per le importazioni da bunq',
+ 'do_prereq_spectre' => 'Prerequisiti per le importazioni usando Spectre',
+ 'do_prereq_plaid' => 'Prerequisiti per le importazioni usando Plaid',
+ 'do_prereq_yodlee' => 'Prerequisiti per le importazioni usando Yodlee',
+ 'do_prereq_quovo' => 'Prerequisiti per le importazioni usando Quovo',
+ // provider config box (index)
+ 'can_config_title' => 'Configurazione di importazione',
+ 'can_config_intro' => 'Alcuni metodi di importazione possono essere configurati a tuo piacimento. Hanno ulteriori impostazioni che puoi modificare.',
+ 'do_config_fake' => 'Configurazione per il fornitore fittizio',
+ 'do_config_file' => 'Configurazione per le importazioni da file',
+ 'do_config_bunq' => 'Configurazione per le importazioni da bunq',
+ 'do_config_spectre' => 'Configurazione per importazioni da Spectre',
+ 'do_config_plaid' => 'Configurazione per importazioni da Plaid',
+ 'do_config_yodlee' => 'Configurazione per importazioni da Yodlee',
+ 'do_config_quovo' => 'Configurazione per importazioni da Quovo',
+
+ // prerequisites:
+ 'prereq_fake_title' => 'Prerequisiti per un\'importazione dal fornitore di importazione fittizio',
+ 'prereq_fake_text' => 'Questo provider fittizio richiede una chiave API fittizia. Deve contenere 32 caratteri. È possibile utilizzare questa: 123456789012345678901234567890AA',
+ 'prereq_spectre_title' => 'Prerequisiti per un\'importazione utilizzando le API di Spectre',
+ 'prereq_spectre_text' => 'Per l\'importazione dei dati attraverso le API Spectre (v4), devi fornire a Firefly III due valori segreti. Questi si possono trovare nella pagina dei segreti.',
+ 'prereq_spectre_pub' => 'Allo stesso modo, l\'API Spectre deve conoscere la chiave pubblica che vedi qui sotto. Senza di essa, non ti riconoscerà . Per favore inserisci questa chiave pubblica nella tua pagina dei segreti.',
+ 'prereq_bunq_title' => 'Prerequisiti per un\'importazione da bunq',
+ 'prereq_bunq_text' => 'Per importare da bunq, è necessario ottenere una chiave API. Puoi farlo attraverso l\'app. Si noti che la funzione di importazione per bunq è in BETA. È stato testato solo contro l\'API sandbox.',
+ 'prereq_bunq_ip' => 'bunq richiede il tuo indirizzo IP esterno. Firefly III ha provato a riempire questo campo utilizzando il servizio ipify. Assicurati che questo indirizzo IP sia corretto altrimenti l\'importazione fallirà .',
+ // prerequisites success messages:
+ 'prerequisites_saved_for_fake' => 'Chiave API fittizia memorizzata correttamente!',
+ 'prerequisites_saved_for_spectre' => 'ID dell\'app e segreto memorizzati!',
+ 'prerequisites_saved_for_bunq' => 'Chiave API e IP memorizzati!',
+
+ // job configuration:
+ 'job_config_apply_rules_title' => 'Configurazione del lavoro - applicare le tue regole?',
+ 'job_config_apply_rules_text' => 'Una volta avviato il fornitore fittizio, le tue regole possono essere applicate alle transazioni. Questo aggiunge del tempo all\'importazione.',
+ 'job_config_input' => 'Il tuo input',
+ // job configuration for the fake provider:
+ 'job_config_fake_artist_title' => 'Inserisci il nome dell\'album',
+ 'job_config_fake_artist_text' => 'Molte routine di importazione presentano alcuni passaggi di configurazione da eseguire. Nel caso del fornitore di importazione fittizio, è necessario rispondere ad alcune domande strane. In questo caso, inserire "David Bowie" per continuare.',
+ 'job_config_fake_song_title' => 'Inserisci il nome del brano',
+ 'job_config_fake_song_text' => 'Menziona la canzone "Golden years" per continuare con l\'importazione fittizia.',
+ 'job_config_fake_album_title' => 'Inserisci il nome dell\'album',
+ 'job_config_fake_album_text' => 'Alcune routine di importazione richiedono dati aggiuntivi a metà dell\'importazione. Nel caso del fornitore di importazione fittizio, è necessario rispondere ad alcune domande strane. Inserire "Station to station" per continuare.',
+ // job configuration form the file provider
+ 'job_config_file_upload_title' => 'Configurazione importazione (1/4) - Carica il tuo file',
+ 'job_config_file_upload_text' => 'Questa routine ti aiuterà a importare i file dalla tua banca in Firefly III. ',
+ 'job_config_file_upload_help' => 'Seleziona il tuo file. Assicurati che il file sia codificato in UTF-8.',
+ 'job_config_file_upload_config_help' => 'Se hai precedentemente importato i dati in Firefly III, potresti avere un file di configurazione, che preimposterà i valori di configurazione per te. Per alcune banche, altri utenti hanno gentilmente fornito il loro file di configurazione',
+ 'job_config_file_upload_type_help' => 'Seleziona il tipo di file che caricherai',
+ 'job_config_file_upload_submit' => 'Carica i file',
+ 'import_file_type_csv' => 'CSV (valori separati da virgola)',
+ 'file_not_utf8' => 'Il file che hai caricato non è codificato come UTF-8 o ASCII. Firefly III non può gestire tali file. Utilizzare Notepad++ o Sublime per convertire il file in UTF-8.',
+ 'job_config_uc_title' => 'Configurazione di importazione (2/4) - Impostazione di base dei file',
+ 'job_config_uc_text' => 'Per poter importare correttamente il tuo file, ti preghiamo di convalidare le opzioni di seguito.',
+ 'job_config_uc_header_help' => 'Seleziona questa casella se la prima riga del tuo file CSV sono i titoli delle colonne.',
+ 'job_config_uc_date_help' => 'Formato della data e ora nel tuo file. Segui il formato indicato in questa pagina. Il valore predefinito analizzerà le date che assomigliano a questa: :dateExample.',
+ 'job_config_uc_delimiter_help' => 'Scegli il delimitatore di campo che viene utilizzato nel file di ingresso. Se non si è sicuri, la virgola è l\'opzione più sicura.',
+ 'job_config_uc_account_help' => 'Se il tuo file NON contiene informazioni sui tuoi conti di attività , utilizza questo menu a discesa per selezionare a quale conto appartengono le transazioni nel file.',
+ 'job_config_uc_apply_rules_title' => 'Applica regole',
+ 'job_config_uc_apply_rules_text' => 'Applica le tue regole ad ogni transazione importata. Si noti che questo rallenta l\'importazione in modo significativo.',
+ 'job_config_uc_specifics_title' => 'Opzioni specifiche della banca',
+ 'job_config_uc_specifics_txt' => 'Alcune banche forniscono file formattati in modo errato. Firefly III può sistemarli automaticamente. Se la tua banca rende disponibili tali file ma non è elencata qui, ti preghiamo di segnalare il problema su GitHub.',
+ 'job_config_uc_submit' => 'Continua',
+ 'invalid_import_account' => 'Hai selezionato un conto non valido su cui effettuare l\'importazione.',
+ // job configuration for Spectre:
+ 'job_config_spectre_login_title' => 'Scegli il tuo login',
+ 'job_config_spectre_login_text' => 'Firefly III ha rilevato :count login esistenti nel tuo account Spectre. Quale vorresti usare per l\'importazione?',
+ 'spectre_login_status_active' => 'Attivo',
+ 'spectre_login_status_inactive' => 'Inattivo',
+ 'spectre_login_status_disabled' => 'Disabilitato',
+ 'spectre_login_new_login' => 'Accedi con un\'altra banca o con una di queste banche con credenziali diverse.',
+ 'job_config_spectre_accounts_title' => 'Seleziona i conti dai quali importare',
+ 'job_config_spectre_accounts_text' => 'Hai selezionato ":name" (:country). Hai :count conti disponibili da questo fornitore. Seleziona i conti attività di Firefly III in cui devono essere memorizzate le transazioni da questi conti. Ricorda che, per importare i dati, sia l\'account Firefly III sia l\'account ":name" devono avere la stessa valuta.',
+ 'spectre_no_supported_accounts' => 'Non puoi importare da questo conto perché le valute non corrispondono.',
+ 'spectre_do_not_import' => '(non importare)',
+ 'spectre_no_mapping' => 'Sembra che tu non abbia selezionato nessun account da cui importare.',
+ 'imported_from_account' => 'Importato da ":account"',
+ 'spectre_account_with_number' => 'Conto :number',
+ // job configuration for bunq:
+ 'job_config_bunq_accounts_title' => 'Account bunq',
+ 'job_config_bunq_accounts_text' => 'Questi sono i conti associati al tuo account bunq. Seleziona i conti dai quali vuoi effettuare l\'importazione e in quale conto devono essere importate le transazioni.',
+ 'bunq_no_mapping' => 'Sembra che tu non abbia selezionato nessun account.',
+ 'should_download_config' => 'You should download the configuration file for this job. This will make future imports way easier.',
+ 'share_config_file' => 'If you have imported data from a public bank, you should share your configuration file so it will be easy for other users to import their data. Sharing your configuration file will not expose your financial details.',
+
+ // keys from "extra" array:
+ 'spectre_extra_key_iban' => 'IBAN',
+ 'spectre_extra_key_swift' => 'SWIFT',
+ 'spectre_extra_key_status' => 'Stato',
+ 'spectre_extra_key_card_type' => 'Tipo carta',
+ 'spectre_extra_key_account_name' => 'Nome conto',
+ 'spectre_extra_key_client_name' => 'Nome cliente',
+ 'spectre_extra_key_account_number' => 'Numero conto',
+ 'spectre_extra_key_blocked_amount' => 'Importo bloccato',
+ 'spectre_extra_key_available_amount' => 'Importo disponibile',
+ 'spectre_extra_key_credit_limit' => 'Limite di credito',
+ 'spectre_extra_key_interest_rate' => 'Tasso d\'interesse',
+ 'spectre_extra_key_expiry_date' => 'Data scadenza',
+ 'spectre_extra_key_open_date' => 'Data apertura',
+ 'spectre_extra_key_current_time' => 'Ora corrente',
+ 'spectre_extra_key_current_date' => 'Data corrente',
+ 'spectre_extra_key_cards' => 'Carte',
+ 'spectre_extra_key_units' => 'Unità ',
+ 'spectre_extra_key_unit_price' => 'Prezzo unitario',
+ 'spectre_extra_key_transactions_count' => 'Conteggio transazioni',
+
+ // specifics:
+ 'specific_ing_name' => 'ING NL',
+ 'specific_ing_descr' => 'Crea descrizioni migliori nelle esportazioni ING',
+ 'specific_sns_name' => 'SNS / Volksbank NL',
+ 'specific_sns_descr' => 'Elimina le virgolette dai file di esportazione di SNS / Volksbank',
+ 'specific_abn_name' => 'ABN AMRO NL',
+ 'specific_abn_descr' => 'Risolvi i possibili problemi con i file ABN AMRO',
+ 'specific_rabo_name' => 'Rabobank NL',
+ 'specific_rabo_descr' => 'Risolvi i possibili problemi con i file Rabobank',
+ 'specific_pres_name' => 'CA finanziaria scelta dal Presidente',
+ 'specific_pres_descr' => 'Risolvi i possibili problemi con i file da PC',
+ // job configuration for file provider (stage: roles)
+ 'job_config_roles_title' => 'Configurazione di importazione (3/4) - Definisci il ruolo di ogni colonna',
+ 'job_config_roles_text' => 'Ogni colonna nel tuo file CSV contiene determinati dati. Si prega di indicare il tipo di dati che l\'importatore dovrebbe aspettarsi. L\'opzione per "mappare" i dati significa che collegherete ogni voce trovata nella colonna con un valore nel vostro database. Una colonna spesso mappata è la colonna che contiene l\'IBAN del conto. Questo può essere facilmente abbinato all\'IBAN già presente nel tuo database.',
+ 'job_config_roles_submit' => 'Continua',
+ 'job_config_roles_column_name' => 'Nome della colonna',
+ 'job_config_roles_column_example' => 'Dati di esempio della colonna',
+ 'job_config_roles_column_role' => 'Significato dei dati della colonna',
+ 'job_config_roles_do_map_value' => 'Mappa questi valori',
+ 'job_config_roles_no_example' => 'Nessun dato di esempio disponibile',
+ 'job_config_roles_fa_warning' => 'Se contrassegni una colonna come contenente un importo in una valuta straniera, devi anche impostare la colonna che contiene di quale valuta si tratta.',
+ 'job_config_roles_rwarning' => 'Come minimo, contrassegna una colonna come colonna dell\'importo. Si consiglia di selezionare anche una colonna per la descrizione, la data e il conto opposto.',
+ 'job_config_roles_colum_count' => 'Colonna',
+ // job config for the file provider (stage: mapping):
+ 'job_config_map_title' => 'Configurazione di importazione (4/4) - Collega i dati importati con i dati di Firefly III',
+ 'job_config_map_text' => 'Nelle seguenti tabelle, il valore a sinistra mostra le informazioni trovate nel file caricato. È tuo compito mappare questo valore, se possibile, su un valore già presente nel tuo database. Firefly si atterrà a questa mappatura. Se non ci sono valori da mappare o non si desidera mappare il valore specifico, non selezionare niente.',
+ 'job_config_map_nothing' => 'Non ci sono dati presenti nel tuo file che puoi mappare a valori esistenti. Si prega di premere "Inizia l\'importazione" per continuare.',
+ 'job_config_field_value' => 'Valore campo',
+ 'job_config_field_mapped' => 'Mappato a',
+ 'map_do_not_map' => '(non mappare)',
+ 'job_config_map_submit' => 'Inizia l\'importazione',
+
+
+ // import status page:
+ 'import_with_key' => 'Importa con chiave \':key\'',
'status_wait_title' => 'Per favore attendere...',
'status_wait_text' => 'Questa finestra si chiuderà tra un momento.',
- 'status_fatal_title' => 'Si è verificato un errore irreversibile',
- 'status_fatal_text' => 'Si è verificato un errore irreversibile per cui non è stato possibile ripristinare la routine di importazione. Si prega di vedere la spiegazione in rosso qui sotto.',
- 'status_fatal_more' => 'Se l\'errore è un timeout, l\'importazione si sarà interrotta a metà . Per alcune configurazioni del server, o semplicemente il server che si è fermato mentre l\'importazione continua a funzionare in sottofondo. Per verificare questo, controlla il file di registro. Se il problema persiste, prendere in considerazione l\'importazione sulla riga di comando.',
- 'status_ready_title' => 'L\'importazione è pronta per iniziare',
- 'status_ready_text' => 'L\'importazione è pronta per iniziare. È stata eseguita tutta la configurazione necessaria. Si prega di scaricare il file di configurazione. Ti aiuterà con l\'importazione se non dovesse andare come previsto. Per eseguire effettivamente l\'importazione, è possibile eseguire il seguente comando nella console o eseguire l\'importazione basata sul Web. A seconda della configurazione, l\'importazione della console ti darà più feedback.',
- 'status_ready_noconfig_text' => 'L\'importazione è pronta per iniziare. È stata eseguita tutta la configurazione necessaria. Per eseguire effettivamente l\'importazione, è possibile eseguire il seguente comando nella console o eseguire l\'importazione basata sul Web. A seconda della configurazione, l\'importazione della console ti darà più feedback.',
- 'status_ready_config' => 'Scarica configurazione',
- 'status_ready_start' => 'Inizia l\'importazione',
- 'status_ready_share' => 'Ti preghiamo di considerare di scaricare la tua configurazione e di condividerla nel centro di configurazione dell\'importazione. Ciò consentirà ad altri utenti di Firefly III di importare i propri file più facilmente.',
- 'status_job_new' => 'Il lavoro è nuovo di zecca.',
- 'status_job_configuring' => 'L\'importazione è in fase di configurazione.',
- 'status_job_configured' => 'L\'importazione è configurata.',
- 'status_job_running' => 'L\'importazione è in esecuzione... Attendere...',
- 'status_job_error' => 'Il lavoro ha generato un errore.',
- 'status_job_finished' => 'L\'importazione è finita!',
'status_running_title' => 'L\'importazione è in esecuzione',
- 'status_running_placeholder' => 'Si prega di effettuare un aggiornamento...',
- 'status_finished_title' => 'Routine importa terminata',
- 'status_finished_text' => 'La routine di importazione ha importato i tuoi dati.',
- 'status_errors_title' => 'Errori durante l\'importazione',
- 'status_errors_single' => 'Si è verificato un errore durante l\'importazione. Non sembra essere fatale.',
- 'status_errors_multi' => 'Alcuni errori si sono verificati durante l\'importazione. Questi non sembrano essere fatali.',
- 'status_bread_crumb' => 'Stato importazione',
- 'status_sub_title' => 'Stato importazione',
- 'config_sub_title' => 'Configura la tua importazione',
- 'status_finished_job' => 'Le transazioni :count importate possono essere trovate nel tag :tag .',
- 'status_finished_no_tag' => 'Firefly III non ha raccolto alcuna transazione dal tuo file di importazione.',
- 'import_with_key' => 'Importa con chiave \':key\'',
+ 'status_job_running' => 'Attendere, importazione in corso...',
+ 'status_job_storing' => 'Attendere, memorizzazione dei dati...',
+ 'status_job_rules' => 'Attendere, applicazione delle regole...',
+ 'status_fatal_title' => 'Errore fatale',
+ 'status_fatal_text' => 'L\'importazione ha subito un errore irreversibile. Scusa!',
+ 'status_fatal_more' => 'Questo messaggio di errore (probabilmente molto criptico) è completato dai file di log, che puoi trovare sul tuo disco rigido, o nel contenitore Docker da cui esegui Firefly III.',
+ 'status_finished_title' => 'Importazione completata',
+ 'status_finished_text' => 'L\'importazione è finita.',
+ 'finished_with_errors' => 'Si sono verificati alcuni errori durante l\'importazione. Controllali attentamente.',
+ 'unknown_import_result' => 'Risultato di importazione sconosciuto',
+ 'result_no_transactions' => 'Nessuna transazione è stata importata. Forse erano tutte dei duplicati o semplicemente non c\'era nessuna transazione da importare. Forse i file di log possono dirti cosa è successo. Questo è normale se importi i dati regolarmente.',
+ 'result_one_transaction' => 'È stata importata esattamente una transazione. È memorizzata sotto l\'etichetta :tag dove è possibile ispezionarla ulteriormente.',
+ 'result_many_transactions' => 'Firefly III ha importato :count transazioni. Sono memorizzate sotto l\'etichetta :tag dove è possibile ispezionarle ulteriormente.',
- // file, upload something
- 'file_upload_title' => 'Importa configurazione (1/4) - Carica il tuo file',
- 'file_upload_text' => 'Questa routine ti aiuterà a importare file dalla tua banca in Firefly III. Si prega di consultare le pagine di aiuto nell\'angolo in alto a destra.',
- 'file_upload_fields' => 'Campi',
- 'file_upload_help' => 'Seleziona il tuo file',
- 'file_upload_config_help' => 'Se hai precedentemente importato i dati in Firefly III, potresti avere un file di configurazione, con preimpostato i valori di configurazione per te. Per alcune banche, altri utenti hanno gentilmente fornito il loro configurazione file ',
- 'file_upload_type_help' => 'Seleziona il tipo di file che carichi',
- 'file_upload_submit' => 'File caricati',
- // file, upload types
- 'import_file_type_csv' => 'CSV (valori separati da virgola)',
+ // general errors and warnings:
+ 'bad_job_status' => 'Per accedere a questa pagina, il tuo lavoro di importazione non può avere lo stato ":status".',
- // file, initial config for CSV
- 'csv_initial_title' => 'Importa configurazione (2/4) - Impostazione di importazione CSV di base',
- 'csv_initial_text' => 'Per poter importare correttamente il tuo file, ti preghiamo di convalidare le opzioni di seguito.',
- 'csv_initial_box' => 'Configurazione di importazione CSV di base',
- 'csv_initial_box_title' => 'Opzioni di impostazione dell\'importazione CSV di base',
- 'csv_initial_header_help' => 'Seleziona questa casella se la prima riga del tuo file CSV sono i titoli delle colonne.',
- 'csv_initial_date_help' => 'Formato della data e ora nel tuo CSV. Segui il formato indica questa pagina. Il valore predefinito analizzerà le date che assomigliano a questo: :dateExample.',
- 'csv_initial_delimiter_help' => 'Scegli il delimitatore di campo che viene utilizzato nel file di input. Se non si è sicuri, la virgola è l\'opzione più sicura.',
- 'csv_initial_import_account_help' => 'Se il tuo file CSV NON contiene informazioni sui tuoi conti di attività , utilizza questo menu a discesa per selezionare a quale conto appartengono le transazioni nel CSV.',
- 'csv_initial_submit' => 'Continua con il passo 3/4',
-
- // file, new options:
- 'file_apply_rules_title' => 'Applica regole',
- 'file_apply_rules_description' => 'Applica le tue regole. Si noti che questo rallenta l\'importazione in modo significativo.',
- 'file_match_bills_title' => 'Abbina le bollette',
- 'file_match_bills_description' => 'Abbina le tue bollette ai prelievi di nuova creazione. Si noti che questo rallenta l\'importazione in modo significativo.',
-
- // file, roles config
- 'csv_roles_title' => 'Importa configurazione (3/4) - Definisci il ruolo di ogni colonna',
- 'csv_roles_text' => 'Ogni colonna nel tuo file CSV contiene determinati dati. Si prega di indicare il tipo di dati che l\'importatore dovrebbe aspettarsi. L\'opzione per "mappare" i dati significa che collegherete ogni voce trovata nella colonna con un valore nel vostro database. Una colonna spesso mappata è la colonna che contiene l\'IBAN del conto. Questo può essere facilmente abbinato all\'IBAN già presente nel tuo database.',
- 'csv_roles_table' => 'Tabella',
- 'csv_roles_column_name' => 'Nome colonna',
- 'csv_roles_column_example' => 'Colonna dati esempio',
- 'csv_roles_column_role' => 'Significato dei dati di colonna',
- 'csv_roles_do_map_value' => 'Mappa questi valori',
- 'csv_roles_column' => 'Colonna',
- 'csv_roles_no_example_data' => 'Nessun dato esempio disponibile',
- 'csv_roles_submit' => 'Continua con il punto 4/4',
-
- // not csv, but normal warning
- 'roles_warning' => 'Per lo meno, contrassegnare una colonna come colonna importo. Si consiglia di selezionare anche una colonna per la descrizione, la data e il conto avversario.',
- 'foreign_amount_warning' => 'Se contrassegni una colonna come contenente un importo in una valuta straniera, devi anche impostare la colonna che contiene la valuta in cui si trova.',
-
- // file, map data
- 'file_map_title' => 'Importa configurazione (4/4) - Collega i dati di importazione ai dati di Firefly III',
- 'file_map_text' => 'Nelle seguenti tabelle, il valore a sinistra mostra le informazioni trovate nel file caricato. È tuo compito mappare questo valore, se possibile, su un valore già presente nel tuo database. Firefly si atterrà a questa mappatura. Se non ci sono valori da mappare o non si desidera mappare il valore specifico, selezionare nulla.',
- 'file_map_field_value' => 'Valore campo',
- 'file_map_field_mapped_to' => 'Mappato a',
- 'map_do_not_map' => '(non mappare)',
- 'file_map_submit' => 'Inizia l\'importazione',
- 'file_nothing_to_map' => 'Non ci sono dati presenti nel tuo file che puoi mappare a valori esistenti. Si prega di premere "Inizia l\'importazione" per continuare.',
-
- // map things.
+ // column roles for CSV import:
'column__ignore' => '(ignora questa colonna)',
'column_account-iban' => 'Conto patrimonio (IBAN)',
'column_account-id' => 'Conto patrimonio ID (matching FF3)',
@@ -147,10 +250,10 @@ return [
'column_sepa-ct-id' => 'ID end-to-end del bonifico SEPA',
'column_sepa-ct-op' => 'Conto opposto bonifico SEPA',
'column_sepa-db' => 'Addebito diretto SEPA',
- 'column_sepa-cc' => 'SEPA Clearing Code',
- 'column_sepa-ci' => 'SEPA Creditor Identifier',
+ 'column_sepa-cc' => 'Codice Compensazione SEPA',
+ 'column_sepa-ci' => 'Identificativo Creditore SEPA',
'column_sepa-ep' => 'SEPA External Purpose',
- 'column_sepa-country' => 'SEPA Country Code',
+ 'column_sepa-country' => 'Codice Paese SEPA',
'column_tags-comma' => 'Etichette (separate da virgola)',
'column_tags-space' => 'Etichette (separate con spazio)',
'column_account-number' => 'Conto patrimonio (numero conto)',
@@ -158,48 +261,4 @@ return [
'column_note' => 'Nota(e)',
'column_internal-reference' => 'Riferimento interno',
- // prerequisites
- 'prerequisites' => 'Prerequisiti',
-
- // bunq
- 'bunq_prerequisites_title' => 'Prerequisiti per un\'importazione da bunq',
- 'bunq_prerequisites_text' => 'Per importare da bunq, è necessario ottenere una chiave API. Puoi farlo attraverso l\'applicazione.',
- 'bunq_prerequisites_text_ip' => 'Bunq richiede il tuo indirizzo IP esterno. Firefly III ha provato a riempire questo campo utilizzando il servizio ipify. Assicurati che questo indirizzo IP sia corretto altrimenti l\'importazione fallirà .',
- 'bunq_do_import' => 'Sì, importa da questo conto',
- 'bunq_accounts_title' => 'Conti Bunq',
- 'bunq_accounts_text' => 'Questi sono i conti associati al tuo conto Bunq. Seleziona i conti dai quali vuoi effettuare l\'importazione e in quale conto devono essere importate le transazioni.',
-
- // Spectre
- 'spectre_title' => 'Importa usando uno Spectre',
- 'spectre_prerequisites_title' => 'Prerequisiti per un\'importazione utilizzando Spectre',
- 'spectre_prerequisites_text' => 'In order to import data using the Spectre API (v4), you must provide Firefly III with two secret values. They can be found on the secrets page.',
- 'spectre_enter_pub_key' => 'The import will only work when you enter this public key on your secrets page.',
- 'spectre_accounts_title' => 'Seleziona i conti dai quali importare',
- 'spectre_accounts_text' => 'Ogni account sulla sinistra in basso è stato trovato da Spectre e può essere importato in Firefly III. Seleziona il conto attività che dovrebbe contenere una determinata transazione. Se non desideri importare da un conto specifico, rimuovi il segno di spunta dalla casella di controllo.',
- 'spectre_do_import' => 'Si, importa da questo conto',
- 'spectre_no_supported_accounts' => 'You cannot import from this account due to a currency mismatch.',
-
- // keys from "extra" array:
- 'spectre_extra_key_iban' => 'IBAN',
- 'spectre_extra_key_swift' => 'SWIFT',
- 'spectre_extra_key_status' => 'Stato',
- 'spectre_extra_key_card_type' => 'Tipo carta',
- 'spectre_extra_key_account_name' => 'Nome conto',
- 'spectre_extra_key_client_name' => 'Nome cliente',
- 'spectre_extra_key_account_number' => 'Numero conto',
- 'spectre_extra_key_blocked_amount' => 'Importo bloccato',
- 'spectre_extra_key_available_amount' => 'Importo disponibile',
- 'spectre_extra_key_credit_limit' => 'Limite di credito',
- 'spectre_extra_key_interest_rate' => 'Tasso d\'interesse',
- 'spectre_extra_key_expiry_date' => 'Data scadenza',
- 'spectre_extra_key_open_date' => 'Data apertura',
- 'spectre_extra_key_current_time' => 'Ora corrente',
- 'spectre_extra_key_current_date' => 'Data corrente',
- 'spectre_extra_key_cards' => 'Carte',
- 'spectre_extra_key_units' => 'Unità ',
- 'spectre_extra_key_unit_price' => 'Prezzo unità ',
- 'spectre_extra_key_transactions_count' => 'Conteggio delle transazioni',
-
- // various other strings:
- 'imported_from_account' => 'Importato da ":account"',
];
diff --git a/resources/lang/it_IT/intro.php b/resources/lang/it_IT/intro.php
index df49a56afa..a5b2a44c83 100644
--- a/resources/lang/it_IT/intro.php
+++ b/resources/lang/it_IT/intro.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
// index
'index_intro' => 'Benvenuti nella pagina indice di Firefly III. Si prega di prendersi il tempo necessario per questa introduzione per avere un\'idea di come funziona Firefly III.',
@@ -120,7 +121,7 @@ return [
// create rule:
'rules_create_mandatory' => 'Scegli un titolo descrittivo e imposta quando deve essere attivata la regola.',
- 'rules_create_ruletriggerholder' => 'Aggiungi tutti i trigger che desideri, ma ricorda che TUTTI i trigger devono corrispondere prima che vengano attivate azioni.',
+ 'rules_create_ruletriggerholder' => 'Aggiungi tutti i trigger che desideri, ma ricorda che TUTTI i trigger devono corrispondere prima che vengano attivate le azioni.',
'rules_create_test_rule_triggers' => 'Usa questo pulsante per vedere quali transazioni corrispondono alla tua regola.',
'rules_create_actions' => 'Imposta tutte le azioni che vuoi.',
@@ -132,5 +133,5 @@ return [
'currencies_index_default' => 'Firefly III ha una valuta predefinita. Puoi sempre cambiare valuta usando questi pulsanti.',
// create currency
- 'currencies_create_code' => 'Questo codice dovrebbe essere conforme ISO (Google per la tua nuova valuta).',
+ 'currencies_create_code' => 'Questo codice dovrebbe essere conforme ISO (cercalo con Google per la tua nuova valuta).',
];
diff --git a/resources/lang/it_IT/list.php b/resources/lang/it_IT/list.php
index a2485211bb..4b53c93bf8 100644
--- a/resources/lang/it_IT/list.php
+++ b/resources/lang/it_IT/list.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
'buttons' => 'Pulsanti',
'icon' => 'Icona',
@@ -68,7 +69,7 @@ return [
'bill' => 'Conto',
'withdrawal' => 'Spesa',
'deposit' => 'Deposito',
- 'transfer' => 'Giroconto',
+ 'transfer' => 'Trasferimento',
'type' => 'Tipo',
'completed' => 'Completato',
'iban' => 'IBAN',
@@ -97,24 +98,29 @@ return [
'number_of_transactions' => 'Numero transazioni',
'total_amount' => 'Importo totale',
'sum' => 'Somma',
- 'sum_excluding_transfers' => 'Somma (esclusi i giroconti)',
+ 'sum_excluding_transfers' => 'Somma (esclusi i trasferimenti)',
'sum_withdrawals' => 'Somma prelievi',
'sum_deposits' => 'Somma versamenti',
- 'sum_transfers' => 'Somma giroconti',
+ 'sum_transfers' => 'Somma dei trasferimenti',
'reconcile' => 'Riconcilia',
'account_on_spectre' => 'Conto (Spectre)',
'do_import' => 'Importo da questo conto',
- '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-ct-id' => 'Identificativo End-To-End SEPA',
+ 'sepa-ct-op' => 'Identificativo Conto Oppositore SEPA',
+ 'sepa-db' => 'Identificativo Mandato SEPA',
+ 'sepa-country' => 'Paese SEPA',
+ 'sepa-cc' => 'Codice Compensazione SEPA',
'sepa-ep' => 'SEPA External Purpose',
- 'sepa-ci' => 'SEPA Creditor Identifier',
+ 'sepa-ci' => 'Identificativo Creditore SEPA',
+ 'external_id' => 'ID esterno',
'account_at_bunq' => 'Conto con Bunq',
- 'file_name' => 'File name',
- 'file_size' => 'File size',
- 'file_type' => 'File type',
- 'attached_to' => 'Attached to',
- 'file_exists' => 'File exists',
+ 'file_name' => 'Nome del file',
+ 'file_size' => 'Dimensione del file',
+ 'file_type' => 'Tipo del file',
+ 'attached_to' => 'Allegato a',
+ 'file_exists' => 'Il file esiste',
+ 'spectre_bank' => 'Banca',
+ 'spectre_last_use' => 'Ultimo accesso',
+ 'spectre_status' => 'Stato',
+ 'bunq_payment_id' => 'bunq payment ID',
];
diff --git a/resources/lang/it_IT/pagination.php b/resources/lang/it_IT/pagination.php
index b65f332398..42bde66250 100644
--- a/resources/lang/it_IT/pagination.php
+++ b/resources/lang/it_IT/pagination.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
'previous' => '« Precedente',
'next' => 'Avanti »',
diff --git a/resources/lang/it_IT/passwords.php b/resources/lang/it_IT/passwords.php
index 41f194295b..3e44682679 100644
--- a/resources/lang/it_IT/passwords.php
+++ b/resources/lang/it_IT/passwords.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
'password' => 'Le password devono contenere almeno sei caratteri e devono corrispondere alla conferma.',
'user' => 'Non possiamo trovare un utente con questo indirizzo e-mail.',
diff --git a/resources/lang/it_IT/validation.php b/resources/lang/it_IT/validation.php
index af49eb7aba..f6c286443a 100644
--- a/resources/lang/it_IT/validation.php
+++ b/resources/lang/it_IT/validation.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
'iban' => 'Questo non è un IBAN valido.',
'source_equals_destination' => 'Il conto di origine è uguale al conto di destinazione',
@@ -109,7 +110,8 @@ return [
'in_array' => ':attribute il campo non esiste in :other.',
'present' => ':attribute il campo deve essere presente.',
'amount_zero' => 'L\'importo totale non può essere zero',
- 'secure_password' => 'Questa non è una password sicura. Per favore riprova. Per ulteriori informazioni, visitare https://goo.gl/NCh2tN',
+ 'unique_piggy_bank_for_user' => 'The name of the piggy bank must be unique.',
+ 'secure_password' => 'Questa non è una password sicura. Per favore riprova. Per ulteriori informazioni, visitare http://bit.ly/FF3-password-security',
'attributes' => [
'email' => 'indirizzo email',
'description' => 'descrizione',
@@ -135,15 +137,15 @@ return [
'rule-action.3' => 'regola azione #3',
'rule-action.4' => 'regola azione #4',
'rule-action.5' => 'regola azione #5',
- 'rule-trigger-value.1' => 'regola valore trigger #1',
- 'rule-trigger-value.2' => 'regola valore trigger #2',
- 'rule-trigger-value.3' => 'regola valore trigger #3',
- 'rule-trigger-value.4' => 'regola valore trigger #4',
- 'rule-trigger-value.5' => 'regola valore trigger #5',
- 'rule-trigger.1' => 'esegui regola #1',
- 'rule-trigger.2' => 'esegui regola #2',
- 'rule-trigger.3' => 'esegui regola #3',
- 'rule-trigger.4' => 'esegui regola #4',
- 'rule-trigger.5' => 'esegui regola #5',
+ 'rule-trigger-value.1' => 'valore #1 del trigger della regola',
+ 'rule-trigger-value.2' => 'valore #2 del trigger della regola',
+ 'rule-trigger-value.3' => 'valore #3 del trigger della regola',
+ 'rule-trigger-value.4' => 'valore #4 del trigger della regola',
+ 'rule-trigger-value.5' => 'valore #5 del trigger della regola',
+ 'rule-trigger.1' => 'trigger #1 della regola',
+ 'rule-trigger.2' => 'trigger #2 della regola',
+ 'rule-trigger.3' => 'trigger #3 della regola',
+ 'rule-trigger.4' => 'trigger #4 della regola',
+ 'rule-trigger.5' => 'trigger #5 della regola',
],
];
diff --git a/resources/lang/nl_NL/auth.php b/resources/lang/nl_NL/auth.php
index 948cf45eba..8ef1c2fa01 100644
--- a/resources/lang/nl_NL/auth.php
+++ b/resources/lang/nl_NL/auth.php
@@ -1,9 +1,8 @@
.
*/
-return [
- /*
- |--------------------------------------------------------------------------
- | Authentication Language Lines
- |--------------------------------------------------------------------------
- |
- | The following language lines are used during authentication for various
- | messages that we need to display to the user. You are free to modify
- | these language lines according to your application's requirements.
- |
- */
+declare(strict_types=1);
+return [
'failed' => 'Deze gegevens zijn niet correct.',
'throttle' => 'Te veel inlogpogingen. Probeer opnieuw in :seconds seconden.',
];
diff --git a/resources/lang/nl_NL/bank.php b/resources/lang/nl_NL/bank.php
index 8826020cbf..5d00b1e685 100644
--- a/resources/lang/nl_NL/bank.php
+++ b/resources/lang/nl_NL/bank.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
];
diff --git a/resources/lang/nl_NL/breadcrumbs.php b/resources/lang/nl_NL/breadcrumbs.php
index c15096d016..81dd5186bc 100644
--- a/resources/lang/nl_NL/breadcrumbs.php
+++ b/resources/lang/nl_NL/breadcrumbs.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
'home' => 'Home',
'edit_currency' => 'Wijzig valuta ":name"',
diff --git a/resources/lang/nl_NL/components.php b/resources/lang/nl_NL/components.php
index 4d040c691c..c3369d4673 100644
--- a/resources/lang/nl_NL/components.php
+++ b/resources/lang/nl_NL/components.php
@@ -1,5 +1,4 @@
.
*/
+declare(strict_types=1);
+
return [
// profile
'personal_access_tokens' => 'Persoonlijke toegangstokens',
diff --git a/resources/lang/nl_NL/config.php b/resources/lang/nl_NL/config.php
index 63b564e67a..d2e66fcf86 100644
--- a/resources/lang/nl_NL/config.php
+++ b/resources/lang/nl_NL/config.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
'html_language' => 'nl',
'locale' => 'nl, Dutch, nl_NL, nl_NL.utf8, nl_NL.UTF-8',
diff --git a/resources/lang/nl_NL/csv.php b/resources/lang/nl_NL/csv.php
index 622a49202a..aae109a40a 100644
--- a/resources/lang/nl_NL/csv.php
+++ b/resources/lang/nl_NL/csv.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
];
diff --git a/resources/lang/nl_NL/demo.php b/resources/lang/nl_NL/demo.php
index 7611dbfe17..5f6ed1f0b2 100644
--- a/resources/lang/nl_NL/demo.php
+++ b/resources/lang/nl_NL/demo.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
'no_demo_text' => 'Sorry, er is geen extra uitleg voor deze pagina.',
'see_help_icon' => 'Maar het -icoontje kan je wellicht meer vertellen.',
@@ -32,5 +33,5 @@ return [
'currencies-index' => 'Firefly ondersteunt meerdere valuta\'s. Hoewel het standaard de Euro is kan je ook kiezen voor de US dollar of een van de vele anderen. Er is een kleine selectie valuta meegeleverd maar je kan je eigen valuta toevoegen. Het veranderen van de standaardvaluta verandert de bestaande transacties niet: Firefly III ondersteunt het gebruik van meerdere valuta op hetzelfde moment.',
'transactions-index' => 'Deze uitgaven, inkomsten en overschrijvingen zijn niet heel fantasierijk. Ze zijn automatisch gegenereerd.',
'piggy-banks-index' => 'Zoals je kan zien zijn er drie spaarpotjes. Gebruik de plus- en minknoppen om het bedrag in de spaarpotjes te veranderen. Klik op de naam van het spaarpotje om er de geschiedenis van te zien.',
- 'import-index' => 'Uiteraard kan je elk CSV bestand importeren in Firefly III',
+ 'import-index' => 'Je kan elk CSV bestand importeren met Firefly III. Het is ook mogelijk om transacties te importeren van bunq en Spectre. Andere verzamelbedrijven worden ook geïntegreerd. De demo-gebruiker mag alleen de "nep"-importhulp gebruiken. Deze genereert een paar willekeurige transacties om te laten zien hoe het werkt.',
];
diff --git a/resources/lang/nl_NL/firefly.php b/resources/lang/nl_NL/firefly.php
index e31e56d599..051852c28d 100644
--- a/resources/lang/nl_NL/firefly.php
+++ b/resources/lang/nl_NL/firefly.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
// general stuff:
'close' => 'Sluiten',
@@ -179,6 +180,7 @@ return [
'authorization_request_intro' => ':client vraagt ​​toestemming om toegang te krijgen tot je financiële administratie. Wil je :client autoriseren om toegang te krijgen tot je gegevens?',
'scopes_will_be_able' => 'Deze applicatie krijgt toegang tot:',
'button_authorize' => 'Toestaan',
+ 'none_in_select_list' => '(geen)',
// check for updates:
'update_check_title' => 'Op updates controleren',
@@ -666,6 +668,7 @@ return [
'bill_will_automatch' => 'Waar van toepassing wordt dit contract automatisch gekoppeld aan transacties',
'skips_over' => 'slaat over',
'bill_store_error' => 'Er ging wat fout bij het opslaan van het contract. Kijk in de logbestanden',
+ 'list_inactive_rule' => 'inactieve regel',
// accounts:
'details_for_asset' => 'Overzicht voor betaalrekening ":name"',
@@ -801,6 +804,7 @@ return [
'opt_group_savingAsset' => 'Spaarrekeningen',
'opt_group_sharedAsset' => 'Gedeelde betaalrekeningen',
'opt_group_ccAsset' => 'Creditcards',
+ 'opt_group_cashWalletAsset' => 'Cash portomonees',
'notes' => 'Notities',
'unknown_journal_error' => 'Kon de transactie niet opslaan. Kijk in de logbestanden.',
@@ -816,6 +820,7 @@ return [
'language' => 'Taal',
'new_savings_account' => ':bank_name spaarrekening',
'cash_wallet' => 'Cash-rekening',
+ 'currency_not_present' => 'Geen zorgen als de valuta die je gewend bent er niet tussen staat. Je kan je eigen valuta maken onder Opties > Valuta.',
// home page:
'yourAccounts' => 'Je betaalrekeningen',
@@ -1013,6 +1018,7 @@ return [
'remove_money_from_piggy_title' => 'Haal geld uit spaarpotje ":name"',
'add' => 'Toevoegen',
'no_money_for_piggy' => 'Er is geen geld voor dit spaarpotje.',
+ 'suggested_savings_per_month' => 'Voorgesteld per maand',
'remove' => 'Verwijderen',
'max_amount_add' => 'Hooguit toe te voegen',
@@ -1148,27 +1154,9 @@ return [
'no_edit_multiple_left' => 'Je hebt geen geldige transacties geselecteerd.',
'cannot_convert_split_journal' => 'Kan geen gesplitste transactie omzetten',
- // import bread crumbs and titles:
- 'import' => 'Import',
- 'import_data' => 'Importeer data',
- 'import_general_index_file' => 'Importeer een bestand',
- 'import_from_bunq' => 'Importeer uit bunq',
- 'import_using_spectre' => 'Importeer via Spectre',
- 'import_using_plaid' => 'Importeer via Plaid',
- 'import_config_bread_crumb' => 'Instellen van je import',
-
- // import index page:
+ // Import page (general strings only)
'import_index_title' => 'Gegevens importeren in Firefly III',
- 'import_index_sub_title' => 'Index',
- 'import_general_index_intro' => 'Dit is de import-routine van Firefly III. Er zijn verschillende manieren om gegevens te importeren in Firefly III, hier als knoppen weergegeven.',
- 'upload_error' => 'Het bestand dat je hebt geüpload kan niet gebruikt worden. Het is wellicht het verkeerde type of de verkeerde encoding. In de logbestanden staat meer info.',
- 'reset_import_settings_title' => 'Reset importconfiguratie',
- 'reset_import_settings_text' => 'Gebruik deze links om importinstellingen voor specifieke providers te resetten. Handig als verkeerde instellingen voorkomen dat je verder kan.',
- 'reset_settings_bunq' => 'Verwijdert de bunq API key, je externe IP adres zoals Firefly III die kent, en de voor bunq gegenereerde RSA sleutels.',
- 'reset_settings_spectre' => 'Verwijdert je Spectre secrets en ID\'s. Dit verwijdert ook je Spectre keypair. Vergeet die niet te updaten.',
- 'settings_reset_for_bunq' => 'Bunq-instellingen zijn gereset.',
- 'settings_reset_for_spectre' => 'Spectre-instellingen zijn gereset.',
-
+ 'import_data' => 'Importeer data',
// sandstorm.io errors and messages:
'sandstorm_not_available' => 'Deze functie werkt niet als je Firefly III gebruikt in combinatie met Sandstorm.IO.',
diff --git a/resources/lang/nl_NL/form.php b/resources/lang/nl_NL/form.php
index 869a935250..748af68a19 100644
--- a/resources/lang/nl_NL/form.php
+++ b/resources/lang/nl_NL/form.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
// new user:
'bank_name' => 'Banknaam',
@@ -184,6 +185,13 @@ return [
'blocked' => 'Is geblokkeerd?',
'blocked_code' => 'Reden voor blokkade',
+ // import
+ 'apply_rules' => 'Regels toepassen',
+ 'artist' => 'Artiest',
+ 'album' => 'Album',
+ 'song' => 'Nummer',
+
+
// admin
'domain' => 'Domein',
'single_user_mode' => 'Registratie uitgeschakelen',
diff --git a/resources/lang/nl_NL/import.php b/resources/lang/nl_NL/import.php
index 9a76f0b19b..89381f4bf5 100644
--- a/resources/lang/nl_NL/import.php
+++ b/resources/lang/nl_NL/import.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
- // status of import:
+ // ALL breadcrumbs and subtitles:
+ 'index_breadcrumb' => 'Gegevens importeren in Firefly III',
+ 'prerequisites_breadcrumb_fake' => 'Vereisten voor de nep-importhulp',
+ 'prerequisites_breadcrumb_spectre' => 'Vereisten voor Spectre',
+ 'prerequisites_breadcrumb_bunq' => 'Vereisten voor bunq',
+ 'job_configuration_breadcrumb' => 'Instellingen voor ":key"',
+ 'job_status_breadcrumb' => 'Importstatus voor ":key"',
+ 'cannot_create_for_provider' => 'Firefly III kan niet importeren met behulp van ":provider".',
+
+ // index page:
+ 'general_index_title' => 'Importeer een bestand',
+ 'general_index_intro' => 'Dit is de import-routine van Firefly III. Er zijn verschillende manieren om gegevens te importeren in Firefly III, hier als knoppen weergegeven.',
+ // import provider strings (index):
+ 'button_fake' => 'Nepdata importeren',
+ 'button_file' => 'Importeer een bestand',
+ 'button_bunq' => 'Importeer uit bunq',
+ 'button_spectre' => 'Importeer via Spectre',
+ 'button_plaid' => 'Importeer via Plaid',
+ 'button_yodlee' => 'Importeer via Spectre',
+ 'button_quovo' => 'Importeer via Quovo',
+ // global config box (index)
+ 'global_config_title' => 'Configuratiebestand',
+ 'global_config_text' => 'In de toekomst bevat dit vak voorkeuren die van toepassing zijn op ALLE bovenstaande importproviders.',
+ // prerequisites box (index)
+ 'need_prereq_title' => 'Importvereisten',
+ 'need_prereq_intro' => 'Sommige importmethoden hebben je aandacht nodig voor ze gebruikt kunnen worden. Ze vereisen bijvoorbeeld speciale API-sleutels of geheime waardes. Je kan ze hier instellen. Het icoontje geeft aan of deze vereisten al ingevuld zijn.',
+ 'do_prereq_fake' => 'Vereisten voor de nep-importhulp',
+ 'do_prereq_file' => 'Vereisten voor het importeren van bestanden',
+ 'do_prereq_bunq' => 'Vereisten voor een import van bunq',
+ 'do_prereq_spectre' => 'Vereisten voor een import via Spectre',
+ 'do_prereq_plaid' => 'Vereisten voor een import via Plaid',
+ 'do_prereq_yodlee' => 'Vereisten voor een import via Yodlee',
+ 'do_prereq_quovo' => 'Vereisten voor een import via Quovo',
+ // provider config box (index)
+ 'can_config_title' => 'Importinstellingen',
+ 'can_config_intro' => 'Sommige importmethodes kunnen ingesteld worden zoals jij dat wilt. Er zijn extra instellingen die je aan kan passen.',
+ 'do_config_fake' => 'Instellingen voor de nep-importhulp',
+ 'do_config_file' => 'Instellingen voor importeren van bestanden',
+ 'do_config_bunq' => 'Instellingen voor importeren uit bunq',
+ 'do_config_spectre' => 'Instellingen voor importeren uit Spectre',
+ 'do_config_plaid' => 'Instellingen voor importeren uit Plaid',
+ 'do_config_yodlee' => 'Instellingen voor importeren uit Yodlee',
+ 'do_config_quovo' => 'Instellingen voor importeren uit Quovo',
+
+ // prerequisites:
+ 'prereq_fake_title' => 'Instellingen voor importeren uit de nep-importhulp',
+ 'prereq_fake_text' => 'Deze nep-provider heeft een neppe API key nodig. Deze moet 32 tekens lang zijn. Je mag deze gebruiken: 123456789012345678901234567890AA',
+ 'prereq_spectre_title' => 'Vereisten voor een import via Spectre',
+ 'prereq_spectre_text' => 'Als je gegevens wilt importeren via de Spectre API (v4), moet je een aantal geheime codes bezitten. Ze zijn te vinden op de secrets pagina.',
+ 'prereq_spectre_pub' => 'De Spectre API moet de publieke sleutel kennen die je hieronder ziet. Zonder deze sleutel herkent Spectre je niet. Voer deze publieke sleutel in op je secrets-pagina.',
+ 'prereq_bunq_title' => 'Vereisten aan een import van bunq',
+ 'prereq_bunq_text' => 'Om te importeren vanaf bunq moet je een API key hebben. Deze kan je aanvragen in de app. Denk er aan dat deze functie in BETA is. De code is alleen getest op de sandbox API.',
+ 'prereq_bunq_ip' => 'bunq wilt graag je externe IP-adres weten. Firefly III heeft geprobeerd dit in te vullen met behulp van de ipify-dienst. Zorg dat je zeker weet dat dit IP-adres klopt, want anders zal de import niet werken.',
+ // prerequisites success messages:
+ 'prerequisites_saved_for_fake' => 'Nep API-sleutel is opgeslagen!',
+ 'prerequisites_saved_for_spectre' => 'APP ID en secret opgeslagen!',
+ 'prerequisites_saved_for_bunq' => 'API-sleutel en IP opgeslagen!',
+
+ // job configuration:
+ 'job_config_apply_rules_title' => 'Importinstellingen - regels toepassen?',
+ 'job_config_apply_rules_text' => 'Als de nep-importhulp gedraaid heeft kunnen je regels worden toegepast op de transacties. Dit kost wel tijd.',
+ 'job_config_input' => 'Je invoer',
+ // job configuration for the fake provider:
+ 'job_config_fake_artist_title' => 'Voer albumnaam in',
+ 'job_config_fake_artist_text' => 'Veel importroutines hebben een paar configuratiestappen die je moet doorlopen. In het geval van de nep-importhulp moet je een aantal rare vragen beantwoorden. Voer \'David Bowie\' in om door te gaan.',
+ 'job_config_fake_song_title' => 'Naam van nummer',
+ 'job_config_fake_song_text' => 'Noem het nummer "Golden years" om door te gaan met de nep import.',
+ 'job_config_fake_album_title' => 'Albumnaam invoeren',
+ 'job_config_fake_album_text' => 'Sommige importroutines vereisen extra gegevens halverwege de import. In het geval van de nep-importhulp moet je een aantal rare vragen beantwoorden. Voer "Station naar station" in om door te gaan.',
+ // job configuration form the file provider
+ 'job_config_file_upload_title' => 'Importinstellingen (1/4) - Upload je bestand',
+ 'job_config_file_upload_text' => 'Met deze routine kan je bestanden van je bank importeren in Firefly III. ',
+ 'job_config_file_upload_help' => 'Selecteer je bestand. Zorg ervoor dat het bestand UTF-8 gecodeerd is.',
+ 'job_config_file_upload_config_help' => 'Als je eerder gegevens hebt geïmporteerd in Firefly III, heb je wellicht een configuratiebestand, dat een aantal zaken alvast voor je kan instellen. Voor bepaalde banken hebben andere gebruikers uit de liefde van hun hart het benodigde configuratiebestand gedeeld',
+ 'job_config_file_upload_type_help' => 'Selecteer het type bestand dat je zal uploaden',
+ 'job_config_file_upload_submit' => 'Bestanden uploaden',
+ 'import_file_type_csv' => 'CSV (kommagescheiden waardes)',
+ 'file_not_utf8' => 'Het bestand dat je hebt geüpload, is niet gecodeerd als UTF-8 of ASCII. Firefly III kan dergelijke bestanden niet verwerken. Gebruik Notepad ++ of Sublime om je bestand naar UTF-8 te converteren.',
+ 'job_config_uc_title' => 'Importinstellingen (2/4) - Algemene importinstellingen',
+ 'job_config_uc_text' => 'Om je bestand goed te kunnen importeren moet je deze opties verifiëren.',
+ 'job_config_uc_header_help' => 'Vink hier als de eerste rij kolomtitels bevat.',
+ 'job_config_uc_date_help' => 'Datum/tijd formaat in jouw bestand. Volg het formaat zoals ze het op deze pagina uitleggen. Het standaardformaat ziet er zo uit: :dateExample.',
+ 'job_config_uc_delimiter_help' => 'Kies het veldscheidingsteken dat in jouw bestand wordt gebruikt. Als je het niet zeker weet, is de komma de beste optie.',
+ 'job_config_uc_account_help' => 'Als jouw CSV bestand geen referenties bevat naar jouw betaalrekening(en), geef dan hier aan om welke rekening het gaat.',
+ 'job_config_uc_apply_rules_title' => 'Regels toepassen',
+ 'job_config_uc_apply_rules_text' => 'Past je regels toe op elke geïmporteerde transactie. Merk op dat dit de import aanzienlijk vertraagt.',
+ 'job_config_uc_specifics_title' => 'Bank-specifieke opties',
+ 'job_config_uc_specifics_txt' => 'Sommige banken leveren slecht geformatteerde bestanden aan. Firefly III kan deze automatisch corrigeren. Als jouw bank dergelijke bestanden levert, maar deze hier niet wordt vermeld, open dan een issue op GitHub.',
+ 'job_config_uc_submit' => 'Volgende',
+ 'invalid_import_account' => 'Je hebt een ongeldige betaalrekening geselecteerd om in te importeren.',
+ // job configuration for Spectre:
+ 'job_config_spectre_login_title' => 'Kies je login',
+ 'job_config_spectre_login_text' => 'Firefly III heeft :count bestaande login(s) gevonden in je Spectre-account. Welke wil je gebruiken om van te importeren?',
+ 'spectre_login_status_active' => 'Actief',
+ 'spectre_login_status_inactive' => 'Inactief',
+ 'spectre_login_status_disabled' => 'Uitgeschakeld',
+ 'spectre_login_new_login' => 'Log in via een andere bank, of via een van deze banken met andere inloggegevens.',
+ 'job_config_spectre_accounts_title' => 'Selecteer de rekeningen waaruit je wilt importeren',
+ 'job_config_spectre_accounts_text' => 'Je hebt ":name" (:country) geselecteerd. Je hebt :count rekening(en) bij deze provider. Kies de Firefly III betaalrekening(en) waar je de transacties in wilt opslaan. Denk er aan dat zowel de ":name"-rekeningen als de Firefly III rekeningen dezelfde valuta moeten hebben.',
+ 'spectre_no_supported_accounts' => 'Je kan niet importeren van deze rekening omdat de valuta niet overeen komt.',
+ 'spectre_do_not_import' => '(niet importeren)',
+ 'spectre_no_mapping' => 'Je hebt geen rekeningen geselecteerd om uit te importeren.',
+ 'imported_from_account' => 'Geïmporteerd uit ":account"',
+ 'spectre_account_with_number' => 'Rekening :number',
+ // job configuration for bunq:
+ 'job_config_bunq_accounts_title' => 'bunq rekeningen',
+ 'job_config_bunq_accounts_text' => 'Deze rekeningen zijn geassocieerd met je bunq-account. Kies de rekeningen waar je van wilt importeren, en geef aan waar de gegevens geïmporteerd moeten worden.',
+ 'bunq_no_mapping' => 'Je hebt geen rekeningen geselecteerd om uit te importeren.',
+ 'should_download_config' => 'Download het configuratiebestand voor deze import. Dit maakt toekomstige imports veel eenvoudiger.',
+ 'share_config_file' => 'Als je gegevens hebt geimporteerd van een gewone bank, deel dan je configuratiebestand zodat het makkelijk is voor andere gebruikers om hun gegevens te importeren. Als je je bestand deelt deel je natuurlijk géén privé-gegevens.',
+
+ // keys from "extra" array:
+ 'spectre_extra_key_iban' => 'IBAN',
+ 'spectre_extra_key_swift' => 'SWIFT',
+ 'spectre_extra_key_status' => 'Status',
+ 'spectre_extra_key_card_type' => 'Kaartsoort',
+ 'spectre_extra_key_account_name' => 'Rekeningnaam',
+ 'spectre_extra_key_client_name' => 'Klantnaam',
+ 'spectre_extra_key_account_number' => 'Rekeningnummer',
+ 'spectre_extra_key_blocked_amount' => 'Geblokkeerd bedrag',
+ 'spectre_extra_key_available_amount' => 'Beschikbaar bedrag',
+ 'spectre_extra_key_credit_limit' => 'Kredietlimiet',
+ 'spectre_extra_key_interest_rate' => 'Rente',
+ 'spectre_extra_key_expiry_date' => 'Vervaldatum',
+ 'spectre_extra_key_open_date' => 'Openingsdatum',
+ 'spectre_extra_key_current_time' => 'Huidige tijd',
+ 'spectre_extra_key_current_date' => 'Huidige datum',
+ 'spectre_extra_key_cards' => 'Kaarten',
+ 'spectre_extra_key_units' => 'Eenheden',
+ 'spectre_extra_key_unit_price' => 'Prijs per eenheid',
+ 'spectre_extra_key_transactions_count' => 'Transacties',
+
+ // specifics:
+ 'specific_ing_name' => 'ING NL',
+ 'specific_ing_descr' => 'Maak betere beschrijvingen in de export van ING',
+ 'specific_sns_name' => 'SNS / Volksbank NL',
+ 'specific_sns_descr' => 'Trim citaten uit exportbestanden van SNS / Volksbank',
+ 'specific_abn_name' => 'ABN AMRO NL',
+ 'specific_abn_descr' => 'Lost mogelijke problemen op met ABN AMRO-bestanden',
+ 'specific_rabo_name' => 'Rabobank NL',
+ 'specific_rabo_descr' => 'Lost mogelijke problemen op met Rabobank txt-bestanden',
+ 'specific_pres_name' => 'President\'s Choice Financial CA',
+ 'specific_pres_descr' => 'Lost mogelijke problemen op met PC bestanden',
+ // job configuration for file provider (stage: roles)
+ 'job_config_roles_title' => 'Importinstellingen (3/4) - rol van elke kolom definiëren',
+ 'job_config_roles_text' => 'Elke kolom in je CSV-bestand bevat bepaalde gegevens. Gelieve aan te geven wat voor soort gegevens de import-routine kan verwachten. De optie "maak een link" betekent dat u elke vermelding in die kolom linkt aan een waarde uit je database. Een vaak gelinkte kolom is die met de IBAN-code van de tegenrekening. Die kan je dan linken aan de IBAN in jouw database.',
+ 'job_config_roles_submit' => 'Volgende',
+ 'job_config_roles_column_name' => 'Kolomnaam',
+ 'job_config_roles_column_example' => 'Voorbeeldgegevens',
+ 'job_config_roles_column_role' => 'Kolomrol',
+ 'job_config_roles_do_map_value' => 'Maak een link',
+ 'job_config_roles_no_example' => 'Geen voorbeeldgegevens',
+ 'job_config_roles_fa_warning' => 'Als je een kolom markeert als "vreemde valuta" moet je ook aangeven in welke kolom de valuta staat.',
+ 'job_config_roles_rwarning' => 'Geef minstens de kolom aan waar het bedrag in staat. Als het even kan, ook een kolom voor de omschrijving, datum en de andere rekening.',
+ 'job_config_roles_colum_count' => 'Kolom',
+ // job config for the file provider (stage: mapping):
+ 'job_config_map_title' => 'Importinstellingen (4/4) - Link importgegevens aan Firefly III-gegevens',
+ 'job_config_map_text' => 'In deze tabellen is de linkerwaarde een waarde uit je CSV bestand. Jij moet de link leggen, als mogelijk, met een waarde uit jouw database. Firefly houdt zich hier aan. Als er geen waarde is, selecteer dan ook niets.',
+ 'job_config_map_nothing' => 'Je gaat geen gegevens importeren die te mappen zijn. Klik op "Start import" om verder te gaan.',
+ 'job_config_field_value' => 'Veldwaarde',
+ 'job_config_field_mapped' => 'Gelinkt aan',
+ 'map_do_not_map' => '(niet linken)',
+ 'job_config_map_submit' => 'Start importeren',
+
+
+ // import status page:
+ 'import_with_key' => 'Import met code \':key\'',
'status_wait_title' => 'Momentje...',
'status_wait_text' => 'Dit vak verdwijnt zometeen.',
- 'status_fatal_title' => 'Er is een fatale fout opgetreden',
- 'status_fatal_text' => 'Een fatale fout opgetreden, waar de import-routine niet van terug heeft. Zie de uitleg in het rood hieronder.',
- 'status_fatal_more' => 'Als de fout een time-out is, zal de import-routine halverwege gestopt zijn. Bij bepaalde serverconfiguraties is het alleen maar de server die gestopt terwijl de import-routine op de achtergrond doorloopt. Controleer de logboekbestanden om te zien wat er aan de hand is. Als het probleem zich blijft voordoen, gebruik dan de command-line opdracht.',
- 'status_ready_title' => 'De import is klaar om te beginnen',
- 'status_ready_text' => 'De import kan beginnen. Alle configuratie is opgeslagen. Download dit bestand. Het kan schelen als je de import opnieuw moet doen. Om daadwerkelijk te beginnen, gebruik je of het commando in je console, of de website. Afhankelijk van hoe je Firefly III hebt ingesteld, geeft de console-methode meer feedback.',
- 'status_ready_noconfig_text' => 'De import kan beginnen. Alle configuratie is opgeslagen. Om daadwerkelijk te beginnen, gebruik je of het commando in je console, of de website. Afhankelijk van hoe je Firefly III hebt ingesteld, geeft de console-methode meer feedback.',
- 'status_ready_config' => 'Download importconfiguratie',
- 'status_ready_start' => 'Start importeren',
- 'status_ready_share' => 'Overweeg om je configuratiebestand te downloaden en te delen op de configuratiebestand-wiki. Hiermee kan je het andere Firefly III gebruikers weer makkelijker maken.',
- 'status_job_new' => 'De import is gloednieuw.',
- 'status_job_configuring' => 'De import wordt geconfigureerd.',
- 'status_job_configured' => 'De import is geconfigureerd.',
- 'status_job_running' => 'De import is bezig.. Momentje..',
- 'status_job_error' => 'De import heeft een fout gegenereerd.',
- 'status_job_finished' => 'Het importeren is voltooid!',
'status_running_title' => 'De import is bezig',
- 'status_running_placeholder' => 'Wacht even voor een update...',
- 'status_finished_title' => 'Importeren is klaar',
- 'status_finished_text' => 'De import is klaar.',
- 'status_errors_title' => 'Fouten tijdens het importeren',
- 'status_errors_single' => 'Er is een niet-fatale fout opgetreden tijdens het importeren.',
- 'status_errors_multi' => 'Er zijn een aantal niet-fatale fouten opgetreden tijdens het importeren.',
- 'status_bread_crumb' => 'Status van importeren',
- 'status_sub_title' => 'Status van importeren',
- 'config_sub_title' => 'Instellen van je import',
- 'status_finished_job' => 'De :count geïmporteerde transacties kan je vinden onder tag :tag.',
- 'status_finished_no_tag' => 'Er is niets uit je bestand geïmporteerd.',
- 'import_with_key' => 'Import met code \':key\'',
+ 'status_job_running' => 'Even geduld, de import loopt...',
+ 'status_job_storing' => 'Even geduld, de gegevens worden opgeslagen...',
+ 'status_job_rules' => 'Even gedult, je regels worden toegepast...',
+ 'status_fatal_title' => 'Onherstelbare fout',
+ 'status_fatal_text' => 'De import is tegen een fout aangelopen waar-ie niet meer van terug kan komen. Excuses!',
+ 'status_fatal_more' => 'Deze (waarschijnlijk zeer cryptische) foutmelding wordt aangevuld door logbestanden, die je kan vinden op je harde schijf of in de Docker-container waar je Firefly III draait.',
+ 'status_finished_title' => 'Importeren voltooid',
+ 'status_finished_text' => 'Het importeren is voltooid.',
+ 'finished_with_errors' => 'Er zijn enkele fouten opgetreden tijdens het importeren. Beoordeel ze zorgvuldig.',
+ 'unknown_import_result' => 'Onbekend importresultaat',
+ 'result_no_transactions' => 'Er zijn geen transacties geïmporteerd. Misschien waren ze allemaal dubbel, of er zijn simpelweg geen transacties gevonden die kunnen worden geïmporteerd. Misschien kunnen de logbestanden je vertellen wat er is gebeurd. Als je regelmatig gegevens importeert, is dit normaal.',
+ 'result_one_transaction' => 'Precies één transactie is geïmporteerd. Je kan deze bekijken onder tag :tag.',
+ 'result_many_transactions' => 'Firefly III heeft :count transacties geïmporteerd. Je kan ze inspecteren onder tag :tag.',
- // file, upload something
- 'file_upload_title' => 'Importinstellingen (1/4) - Upload je bestand',
- 'file_upload_text' => 'Deze pagina\'s helpen je bestanden van je bank te importeren in Firefly III. Gebruik de hulp-pagina\'s linksboven voor meer informatie.',
- 'file_upload_fields' => 'Velden',
- 'file_upload_help' => 'Selecteer je bestand',
- 'file_upload_config_help' => 'Als je eerder gegevens hebt geïmporteerd in Firefly III, heb je wellicht een configuratiebestand, dat een aantal zaken alvast voor je kan instellen. Voor bepaalde banken hebben andere gebruikers uit de liefde van hun hart het benodigde configuratiebestand gedeeld',
- 'file_upload_type_help' => 'Selecteer het type bestand dat je zal uploaden',
- 'file_upload_submit' => 'Bestanden uploaden',
- // file, upload types
- 'import_file_type_csv' => 'CSV (kommagescheiden waardes)',
+ // general errors and warnings:
+ 'bad_job_status' => 'Om deze pagina te bekijken mag je import-job niet de status ":status" hebben.',
- // file, initial config for CSV
- 'csv_initial_title' => 'Importinstellingen (2/4) - Algemene CVS importinstellingen',
- 'csv_initial_text' => 'Om je bestand goed te kunnen importeren moet je deze opties verifiëren.',
- 'csv_initial_box' => 'Algemene CVS importinstellingen',
- 'csv_initial_box_title' => 'Algemene CVS importinstellingen',
- 'csv_initial_header_help' => 'Vink hier als de eerste rij kolomtitels bevat.',
- 'csv_initial_date_help' => 'Datum/tijd formaat in jouw CSV bestand. Volg het formaat zoals ze het op deze pagina uitleggen. Het standaardformaat ziet er zo uit: :dateExample.',
- 'csv_initial_delimiter_help' => 'Kies het veldscheidingsteken dat in jouw bestand wordt gebruikt. Als je het niet zeker weet, is de komma de beste optie.',
- 'csv_initial_import_account_help' => 'Als jouw CSV bestand geen referenties bevat naar jouw rekening(en), geef dan hier aan om welke rekening het gaat.',
- 'csv_initial_submit' => 'Ga verder met stap 3/4',
-
- // file, new options:
- 'file_apply_rules_title' => 'Regels toepassen',
- 'file_apply_rules_description' => 'Past regels toe tijdens de import. Dit vertraagt de import behoorlijk.',
- 'file_match_bills_title' => 'Match contracten',
- 'file_match_bills_description' => 'Checkt of bestaande contracten matchen met nieuwe uitgaves. Dit vertraagt de import behoorlijk.',
-
- // file, roles config
- 'csv_roles_title' => 'Importinstellingen (3/4) - rol van elke kolom definiëren',
- 'csv_roles_text' => 'Elke kolom in je CSV-bestand bevat bepaalde gegevens. Gelieve aan te geven wat voor soort gegevens de import-routine kan verwachten. De optie "maak een link" betekent dat u elke vermelding in die kolom linkt aan een waarde uit je database. Een vaak gelinkte kolom is die met de IBAN-code van de tegenrekening. Die kan je dan linken aan de IBAN in jouw database.',
- 'csv_roles_table' => 'Tabel',
- 'csv_roles_column_name' => 'Kolomnaam',
- 'csv_roles_column_example' => 'Voorbeeldgegevens',
- 'csv_roles_column_role' => 'Kolomrol',
- 'csv_roles_do_map_value' => 'Maak een link',
- 'csv_roles_column' => 'Kolom',
- 'csv_roles_no_example_data' => 'Geen voorbeeldgegevens',
- 'csv_roles_submit' => 'Ga verder met stap 4/4',
-
- // not csv, but normal warning
- 'roles_warning' => 'Geef minstens de kolom aan waar het bedrag in staat. Als het even kan, ook een kolom voor de omschrijving, datum en de andere rekening.',
- 'foreign_amount_warning' => 'Als je een kolom markeert als "vreemde valuta" moet je ook aangeven in welke kolom de valuta staat.',
-
- // file, map data
- 'file_map_title' => 'Importinstellingen (4/4) - Link importgegevens aan Firefly III-gegevens',
- 'file_map_text' => 'In deze tabellen is de linkerwaarde een waarde uit je CSV bestand. Jij moet de link leggen, als mogelijk, met een waarde uit jouw database. Firefly houdt zich hier aan. Als er geen waarde is, selecteer dan ook niets.',
- 'file_map_field_value' => 'Veldwaarde',
- 'file_map_field_mapped_to' => 'Gelinkt aan',
- 'map_do_not_map' => '(niet linken)',
- 'file_map_submit' => 'Start importeren',
- 'file_nothing_to_map' => 'Je gaat geen gegevens importeren die te mappen zijn. Klik op "Start import" om verder te gaan.',
-
- // map things.
+ // column roles for CSV import:
'column__ignore' => '(negeer deze kolom)',
'column_account-iban' => 'Betaalrekening (IBAN)',
'column_account-id' => 'Betaalrekening (ID gelijk aan FF3)',
@@ -158,48 +261,4 @@ return [
'column_note' => 'Opmerking(en)',
'column_internal-reference' => 'Interne referentie',
- // prerequisites
- 'prerequisites' => 'Vereisten',
-
- // bunq
- 'bunq_prerequisites_title' => 'Voorwaarden voor een import van bunq',
- 'bunq_prerequisites_text' => 'Om te importeren vanaf bunq moet je een API key hebben. Deze kan je aanvragen in de app. Denk er aan dat deze functie in BETA is. De code is alleen getest op de sandbox API.',
- 'bunq_prerequisites_text_ip' => 'Bunq wilt graag je externe IP-adres weten. Firefly III heeft geprobeerd dit in te vullen met behulp van de ipify-dienst. Zorg dat je zeker weet dat dit IP-adres klopt, want anders zal de import niet werken.',
- 'bunq_do_import' => 'Ja, importeer van deze rekening',
- 'bunq_accounts_title' => 'Bunq rekeningen',
- 'bunq_accounts_text' => 'Dit zijn de rekeningen uit je bunq-account. Selecteer de rekeningen waaruit je wilt importeren, en welke betaalrekeningen deze transacties op terecht moeten komen.',
-
- // Spectre
- 'spectre_title' => 'Importeer via Spectre',
- 'spectre_prerequisites_title' => 'Voorwaarden voor een import via Spectre',
- 'spectre_prerequisites_text' => 'Als je gegevens wilt importeren via de Spectre API (v4), moet je een aantal geheime codes bezitten. Ze zijn te vinden op de secrets pagina.',
- 'spectre_enter_pub_key' => 'Het importeren werkt alleen als je deze publieke sleutel op je secrets-pagina invoert.',
- 'spectre_accounts_title' => 'Selecteer de accounts waaruit je wilt importeren',
- 'spectre_accounts_text' => 'Links staan de rekeningen die zijn gevonden door Spectre. Ze kunnen worden geïmporteerd in Firefly III. Selecteer er de juiste betaalrekening bij. Verwijder het vinkje als je toch niet van een bepaalde rekening wilt importeren.',
- 'spectre_do_import' => 'Ja, importeer van deze rekening',
- 'spectre_no_supported_accounts' => 'Je kan helaas niet vanaf deze rekening importeren omdat de valuta niet overeenkomt.',
-
- // keys from "extra" array:
- 'spectre_extra_key_iban' => 'IBAN',
- 'spectre_extra_key_swift' => 'SWIFT',
- 'spectre_extra_key_status' => 'Status',
- 'spectre_extra_key_card_type' => 'Kaarttype',
- 'spectre_extra_key_account_name' => 'Rekeningnaam',
- 'spectre_extra_key_client_name' => 'Klantnaam',
- 'spectre_extra_key_account_number' => 'Rekeningnummer',
- 'spectre_extra_key_blocked_amount' => 'Gereserveerd bedrag',
- 'spectre_extra_key_available_amount' => 'Beschikbaar bedrag',
- 'spectre_extra_key_credit_limit' => 'Kredietlimiet',
- 'spectre_extra_key_interest_rate' => 'Rente',
- 'spectre_extra_key_expiry_date' => 'Vervaldatum',
- 'spectre_extra_key_open_date' => 'Openingsdatum',
- 'spectre_extra_key_current_time' => 'Huidige tijd',
- 'spectre_extra_key_current_date' => 'Huidige datum',
- 'spectre_extra_key_cards' => 'Kaarten',
- 'spectre_extra_key_units' => 'Eenheden',
- 'spectre_extra_key_unit_price' => 'Prijs per eenheid',
- 'spectre_extra_key_transactions_count' => 'Transacties',
-
- // various other strings:
- 'imported_from_account' => 'Geïmporteerd uit ":account"',
];
diff --git a/resources/lang/nl_NL/intro.php b/resources/lang/nl_NL/intro.php
index 19344b11b0..777b8f8ad1 100644
--- a/resources/lang/nl_NL/intro.php
+++ b/resources/lang/nl_NL/intro.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
// index
'index_intro' => 'Welkom op de homepage van Firefly III. Neem even de tijd voor deze introductie zodat je Firefly III leert kennen.',
diff --git a/resources/lang/nl_NL/list.php b/resources/lang/nl_NL/list.php
index d33a4301c1..cd17c28646 100644
--- a/resources/lang/nl_NL/list.php
+++ b/resources/lang/nl_NL/list.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
'buttons' => 'Knoppen',
'icon' => 'Icoon',
@@ -111,10 +112,15 @@ return [
'sepa-cc' => 'SEPA vrijwaringscode',
'sepa-ep' => 'SEPA transactiedoeleinde',
'sepa-ci' => 'SEPA crediteuridentificatie',
+ 'external_id' => 'Externe ID',
'account_at_bunq' => 'Bunq-account',
'file_name' => 'Bestandsnaam',
'file_size' => 'Bestandsgrootte',
'file_type' => 'Bestandstype',
'attached_to' => 'Bijlage van',
'file_exists' => 'Bestand bestaat',
+ 'spectre_bank' => 'Bank',
+ 'spectre_last_use' => 'Laatst ingelogd',
+ 'spectre_status' => 'Status',
+ 'bunq_payment_id' => 'bunq betalings-ID',
];
diff --git a/resources/lang/nl_NL/pagination.php b/resources/lang/nl_NL/pagination.php
index a1caed0187..5be4a5ad33 100644
--- a/resources/lang/nl_NL/pagination.php
+++ b/resources/lang/nl_NL/pagination.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
'previous' => '« Vorige',
'next' => 'Volgende »',
diff --git a/resources/lang/nl_NL/passwords.php b/resources/lang/nl_NL/passwords.php
index bb4c4358f6..71bea1d8ce 100644
--- a/resources/lang/nl_NL/passwords.php
+++ b/resources/lang/nl_NL/passwords.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
'password' => 'Wachtwoorden moeten zes karakters lang zijn, en natuurlijk 2x hetzelfde invoeren.',
'user' => 'Geen gebruiker met dat e-mailadres.',
diff --git a/resources/lang/nl_NL/validation.php b/resources/lang/nl_NL/validation.php
index d2d1cf9fc7..d5d0537e2b 100644
--- a/resources/lang/nl_NL/validation.php
+++ b/resources/lang/nl_NL/validation.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
'iban' => 'Dit is niet een geldige IBAN.',
'source_equals_destination' => 'De bronrekening is gelijk aan de doelrekening',
@@ -109,7 +110,8 @@ return [
'in_array' => 'Het :attribute veld bestaat niet in :other.',
'present' => 'Het :attribute veld moet aanwezig zijn.',
'amount_zero' => 'Het totaalbedrag kan niet nul zijn',
- 'secure_password' => 'Dit is geen sterk wachtwoord. Probeer het nog een keer. Zie ook: https://goo.gl/NCh2tN',
+ 'unique_piggy_bank_for_user' => 'De naam van de spaarpot moet uniek zijn.',
+ 'secure_password' => 'Dit is geen sterk wachtwoord. Probeer het nog een keer. Zie ook: http://bit.ly/FF3-password-security',
'attributes' => [
'email' => 'e-mailadres',
'description' => 'omschrijving',
diff --git a/resources/lang/pl_PL/auth.php b/resources/lang/pl_PL/auth.php
index 0ef5506167..cf2ad8e5f2 100644
--- a/resources/lang/pl_PL/auth.php
+++ b/resources/lang/pl_PL/auth.php
@@ -1,9 +1,8 @@
.
*/
-return [
- /*
- |--------------------------------------------------------------------------
- | Authentication Language Lines
- |--------------------------------------------------------------------------
- |
- | The following language lines are used during authentication for various
- | messages that we need to display to the user. You are free to modify
- | these language lines according to your application's requirements.
- |
- */
+declare(strict_types=1);
+return [
'failed' => 'Te poświadczenia nie zgadzają się z naszymi danymi.',
'throttle' => 'Zbyt wiele prób logowania. Spróbuj ponownie za :seconds sekund.',
];
diff --git a/resources/lang/pl_PL/bank.php b/resources/lang/pl_PL/bank.php
index 8826020cbf..5d00b1e685 100644
--- a/resources/lang/pl_PL/bank.php
+++ b/resources/lang/pl_PL/bank.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
];
diff --git a/resources/lang/pl_PL/breadcrumbs.php b/resources/lang/pl_PL/breadcrumbs.php
index 3652e30e29..29b5e21884 100644
--- a/resources/lang/pl_PL/breadcrumbs.php
+++ b/resources/lang/pl_PL/breadcrumbs.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
'home' => 'Strona główna',
'edit_currency' => 'Modyfikuj walutÄ™ ":name"',
diff --git a/resources/lang/pl_PL/components.php b/resources/lang/pl_PL/components.php
index e34586abfd..e9a0269913 100644
--- a/resources/lang/pl_PL/components.php
+++ b/resources/lang/pl_PL/components.php
@@ -1,5 +1,4 @@
.
*/
+declare(strict_types=1);
+
return [
// profile
'personal_access_tokens' => 'Osobisty kod dostępowy',
diff --git a/resources/lang/pl_PL/config.php b/resources/lang/pl_PL/config.php
index 209a790bfc..eedc86c9af 100644
--- a/resources/lang/pl_PL/config.php
+++ b/resources/lang/pl_PL/config.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
'html_language' => 'pl',
'locale' => 'pl, Polish, polski, pl_PL, pl_PL.utf8, pl_PL.UTF-8',
diff --git a/resources/lang/pl_PL/csv.php b/resources/lang/pl_PL/csv.php
index 622a49202a..aae109a40a 100644
--- a/resources/lang/pl_PL/csv.php
+++ b/resources/lang/pl_PL/csv.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
];
diff --git a/resources/lang/pl_PL/demo.php b/resources/lang/pl_PL/demo.php
index c6deb76642..b4ca24333f 100644
--- a/resources/lang/pl_PL/demo.php
+++ b/resources/lang/pl_PL/demo.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
'no_demo_text' => 'Niestety, nie ma dodatkowego tekstu wyjaśniającego demo dla tej strony.',
'see_help_icon' => 'Jednakże ikona w prawym górnym rogu może powiedzieć Ci więcej.',
@@ -32,5 +33,5 @@ return [
'currencies-index' => 'Firefly obsługuje wiele walut. Chociaż domyślnie jest to euro, można go ustawić na dolara amerykańskiego i wiele innych walut. Jak widać niewielki wybór walut został uwzględniony, ale możesz dodać własne, jeśli chcesz. Zmiana domyślnej waluty nie zmieni waluty istniejących transakcji, jednak: Firefly III obsługuje korzystanie z wielu walut w tym samym czasie.',
'transactions-index' => 'Te wydatki, depozyty i transfery nie są szczególnie pomysłowe. Zostały wygenerowane automatycznie.',
'piggy-banks-index' => 'Jak widać, istnieją trzy skarbonki. Użyj przycisków plus i minus, aby wpłynąć na ilość pieniędzy w każdej skarbonce. Kliknij nazwę skarbonki, aby zobaczyć administrację każdej skarbonki.',
- 'import-index' => 'Oczywiście każdy plik CSV można zaimportować do Firefly III',
+ 'import-index' => 'Any CSV file can be imported into Firefly III. It also supports importing data from bunq and Spectre. Other banks and financial aggregators will be implemented in the future. As a demo-user however, you can only see the "fake"-provider in action. It will generate some random transactions to show you how the process works.',
];
diff --git a/resources/lang/pl_PL/firefly.php b/resources/lang/pl_PL/firefly.php
index b6bb8ed4d9..c904d80cd6 100644
--- a/resources/lang/pl_PL/firefly.php
+++ b/resources/lang/pl_PL/firefly.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
// general stuff:
'close' => 'Zamknij',
@@ -179,6 +180,7 @@ return [
'authorization_request_intro' => ':client prosi o pozwolenie na dostęp do Twojej administracji finansowej. Czy chcesz pozwolić :client na dostęp do tych danych?',
'scopes_will_be_able' => 'Ta aplikacja będzie mogła:',
'button_authorize' => 'Autoryzuj',
+ 'none_in_select_list' => '(none)',
// check for updates:
'update_check_title' => 'Sprawdź aktualizacje',
@@ -666,6 +668,7 @@ return [
'bill_will_automatch' => 'Rachunek będzie automatycznie powiązany z pasującymi transakcjami',
'skips_over' => 'pomija',
'bill_store_error' => 'Wystąpił nieoczekiwany błąd podczas zapisywania nowego rachunku. Sprawdź pliki dziennika',
+ 'list_inactive_rule' => 'inactive rule',
// accounts:
'details_for_asset' => 'Szczegóły konta aktywów ":name"',
@@ -801,6 +804,7 @@ return [
'opt_group_savingAsset' => 'Konta oszczędnościowe',
'opt_group_sharedAsset' => 'Współdzielone konta aktywów',
'opt_group_ccAsset' => 'Karty kredytowe',
+ 'opt_group_cashWalletAsset' => 'Cash wallets',
'notes' => 'Notatki',
'unknown_journal_error' => 'Nie można zapisać transakcji. Sprawdź pliki dziennika.',
@@ -816,6 +820,7 @@ return [
'language' => 'Język',
'new_savings_account' => 'Konto oszczędnościowe :bank_name',
'cash_wallet' => 'Portfel gotówkowy',
+ 'currency_not_present' => 'If the currency you normally use is not listed do not worry. You can create your own currencies under Options > Currencies.',
// home page:
'yourAccounts' => 'Twoje konta',
@@ -1013,6 +1018,7 @@ return [
'remove_money_from_piggy_title' => 'Usuń pieniądze ze skarbonki ":name"',
'add' => 'Dodaj',
'no_money_for_piggy' => 'Nie masz pieniędzy, które mógłbyś umieścić w tej skarbonce.',
+ 'suggested_savings_per_month' => 'Suggested per month',
'remove' => 'Usuń',
'max_amount_add' => 'Maksymalną kwotą, którą możesz dodać jest',
@@ -1148,27 +1154,9 @@ return [
'no_edit_multiple_left' => 'Nie wybrałeś żadnych poprawnych transakcji do edycji.',
'cannot_convert_split_journal' => 'Nie można przekonwertować podzielonej transakcji',
- // import bread crumbs and titles:
- 'import' => 'Importuj',
- 'import_data' => 'Importuj dane',
- 'import_general_index_file' => 'Importuj plik',
- 'import_from_bunq' => 'Importuj z bunq',
- 'import_using_spectre' => 'Importuj za pomocÄ… Spectre',
- 'import_using_plaid' => 'Importuj za pomocÄ… Plaid',
- 'import_config_bread_crumb' => 'Skonfiguruj swój import',
-
- // import index page:
+ // Import page (general strings only)
'import_index_title' => 'Importuj dane do Firefly III',
- 'import_index_sub_title' => 'Indeks',
- 'import_general_index_intro' => 'Witamy w procedurze importu Firefly III. Istnieje kilka sposobów importowania danych do Firefly III.',
- 'upload_error' => 'Przesłany plik nie może zostać przetworzony. Prawdopodobnie typ pliku lub kodowanie jest błędne. Pliki dziennika zawierają więcej informacji.',
- 'reset_import_settings_title' => 'Zresetuj konfiguracjÄ™ importu',
- 'reset_import_settings_text' => 'Możesz użyć tych linków, aby zresetować ustawienia importu dla konkretnych dostawców. Jest to przydatne, gdy złe ustawienia uniemożliwiają importowanie danych.',
- 'reset_settings_bunq' => 'Usuń klucz API, lokalny zewnętrzny adres IP oraz klucze RSA związane z Bunq.',
- 'reset_settings_spectre' => 'Usuń identyfikatory i sekrety Spectre. Spowoduje to również usunięcie Twojego klucza Spectre. Pamiętaj, aby zaktualizować nowy.',
- 'settings_reset_for_bunq' => 'Resetowanie ustawień Bunq.',
- 'settings_reset_for_spectre' => 'Resetowanie ustawień Spectre.',
-
+ 'import_data' => 'Importuj dane',
// sandstorm.io errors and messages:
'sandstorm_not_available' => 'Ta funkcja nie jest dostępna, gdy używasz Firefly III w środowisku Sandstorm.io.',
diff --git a/resources/lang/pl_PL/form.php b/resources/lang/pl_PL/form.php
index a776638882..e72c91843f 100644
--- a/resources/lang/pl_PL/form.php
+++ b/resources/lang/pl_PL/form.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
// new user:
'bank_name' => 'Nazwa banku',
@@ -184,6 +185,13 @@ return [
'blocked' => 'Jest zablokowany?',
'blocked_code' => 'Powód blokady',
+ // import
+ 'apply_rules' => 'Apply rules',
+ 'artist' => 'Artist',
+ 'album' => 'Album',
+ 'song' => 'Song',
+
+
// admin
'domain' => 'Domena',
'single_user_mode' => 'Wyłącz rejestrację użytkowników',
diff --git a/resources/lang/pl_PL/import.php b/resources/lang/pl_PL/import.php
index d3d8583a4c..6b2aa6c068 100644
--- a/resources/lang/pl_PL/import.php
+++ b/resources/lang/pl_PL/import.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
- // status of import:
+ // ALL breadcrumbs and subtitles:
+ 'index_breadcrumb' => 'Import data into Firefly III',
+ 'prerequisites_breadcrumb_fake' => 'Prerequisites for the fake import provider',
+ 'prerequisites_breadcrumb_spectre' => 'Prerequisites for Spectre',
+ 'prerequisites_breadcrumb_bunq' => 'Prerequisites for bunq',
+ 'job_configuration_breadcrumb' => 'Configuration for ":key"',
+ 'job_status_breadcrumb' => 'Import status for ":key"',
+ 'cannot_create_for_provider' => 'Firefly III cannot create a job for the ":provider"-provider.',
+
+ // index page:
+ 'general_index_title' => 'Import a file',
+ 'general_index_intro' => 'Welcome to Firefly III\'s import routine. There are a few ways of importing data into Firefly III, displayed here as buttons.',
+ // import provider strings (index):
+ 'button_fake' => 'Fake an import',
+ 'button_file' => 'Import a file',
+ 'button_bunq' => 'Import from bunq',
+ 'button_spectre' => 'Import using Spectre',
+ 'button_plaid' => 'Import using Plaid',
+ 'button_yodlee' => 'Import using Yodlee',
+ 'button_quovo' => 'Import using Quovo',
+ // global config box (index)
+ 'global_config_title' => 'Global import configuration',
+ 'global_config_text' => 'In the future, this box will feature preferences that apply to ALL import providers above.',
+ // prerequisites box (index)
+ 'need_prereq_title' => 'Import prerequisites',
+ 'need_prereq_intro' => 'Some import methods need your attention before they can be used. For example, they might require special API keys or application secrets. You can configure them here. The icon indicates if these prerequisites have been met.',
+ 'do_prereq_fake' => 'Prerequisites for the fake provider',
+ 'do_prereq_file' => 'Prerequisites for file imports',
+ 'do_prereq_bunq' => 'Prerequisites for imports from bunq',
+ 'do_prereq_spectre' => 'Prerequisites for imports using Spectre',
+ 'do_prereq_plaid' => 'Prerequisites for imports using Plaid',
+ 'do_prereq_yodlee' => 'Prerequisites for imports using Yodlee',
+ 'do_prereq_quovo' => 'Prerequisites for imports using Quovo',
+ // provider config box (index)
+ 'can_config_title' => 'Import configuration',
+ 'can_config_intro' => 'Some import methods can be configured to your liking. They have extra settings you can tweak.',
+ 'do_config_fake' => 'Configuration for the fake provider',
+ 'do_config_file' => 'Configuration for file imports',
+ 'do_config_bunq' => 'Configuration for bunq imports',
+ 'do_config_spectre' => 'Configuration for imports from Spectre',
+ 'do_config_plaid' => 'Configuration for imports from Plaid',
+ 'do_config_yodlee' => 'Configuration for imports from Yodlee',
+ 'do_config_quovo' => 'Configuration for imports from Quovo',
+
+ // prerequisites:
+ 'prereq_fake_title' => 'Prerequisites for an import from the fake import provider',
+ 'prereq_fake_text' => 'This fake provider requires a fake API key. It must be 32 characters long. You can use this one: 123456789012345678901234567890AA',
+ 'prereq_spectre_title' => 'Prerequisites for an import using the Spectre API',
+ 'prereq_spectre_text' => 'In order to import data using the Spectre API (v4), you must provide Firefly III with two secret values. They can be found on the secrets page.',
+ 'prereq_spectre_pub' => 'Likewise, the Spectre API needs to know the public key you see below. Without it, it will not recognize you. Please enter this public key on your secrets page.',
+ 'prereq_bunq_title' => 'Prerequisites for an import from bunq',
+ 'prereq_bunq_text' => 'In order to import from bunq, you need to obtain an API key. You can do this through the app. Please note that the import function for bunq is in BETA. It has only been tested against the sandbox API.',
+ 'prereq_bunq_ip' => 'bunq requires your externally facing IP address. Firefly III has tried to fill this in using the ipify service. Make sure this IP address is correct, or the import will fail.',
+ // prerequisites success messages:
+ 'prerequisites_saved_for_fake' => 'Fake API key stored successfully!',
+ 'prerequisites_saved_for_spectre' => 'App ID and secret stored!',
+ 'prerequisites_saved_for_bunq' => 'API key and IP stored!',
+
+ // job configuration:
+ 'job_config_apply_rules_title' => 'Job configuration - apply your rules?',
+ 'job_config_apply_rules_text' => 'Once the fake provider has run, your rules can be applied to the transactions. This adds time to the import.',
+ 'job_config_input' => 'Your input',
+ // job configuration for the fake provider:
+ 'job_config_fake_artist_title' => 'Enter album name',
+ 'job_config_fake_artist_text' => 'Many import routines have a few configuration steps you must go through. In the case of the fake import provider, you must answer some weird questions. In this case, enter "David Bowie" to continue.',
+ 'job_config_fake_song_title' => 'Enter song name',
+ 'job_config_fake_song_text' => 'Mention the song "Golden years" to continue with the fake import.',
+ 'job_config_fake_album_title' => 'Enter album name',
+ 'job_config_fake_album_text' => 'Some import routines require extra data halfway through the import. In the case of the fake import provider, you must answer some weird questions. Enter "Station to station" to continue.',
+ // job configuration form the file provider
+ 'job_config_file_upload_title' => 'Import setup (1/4) - Upload your file',
+ 'job_config_file_upload_text' => 'This routine will help you import files from your bank into Firefly III. ',
+ 'job_config_file_upload_help' => 'Select your file. Please make sure the file is UTF-8 encoded.',
+ 'job_config_file_upload_config_help' => 'If you have previously imported data into Firefly III, you may have a configuration file, which will pre-set configuration values for you. For some banks, other users have kindly provided their configuration file',
+ 'job_config_file_upload_type_help' => 'Select the type of file you will upload',
+ 'job_config_file_upload_submit' => 'Upload files',
+ 'import_file_type_csv' => 'CSV (wartości oddzielone przecinkami)',
+ 'file_not_utf8' => 'The file you have uploaded is not encoded as UTF-8 or ASCII. Firefly III cannot handle such files. Please use Notepad++ or Sublime to convert your file to UTF-8.',
+ 'job_config_uc_title' => 'Import setup (2/4) - Basic file setup',
+ 'job_config_uc_text' => 'To be able to import your file correctly, please validate the options below.',
+ 'job_config_uc_header_help' => 'Check this box if the first row of your CSV file are the column titles.',
+ 'job_config_uc_date_help' => 'Date time format in your file. Follow the format as this page indicates. The default value will parse dates that look like this: :dateExample.',
+ 'job_config_uc_delimiter_help' => 'Choose the field delimiter that is used in your input file. If not sure, comma is the safest option.',
+ 'job_config_uc_account_help' => 'If your file does NOT contain information about your asset account(s), use this dropdown to select to which account the transactions in the file belong to.',
+ 'job_config_uc_apply_rules_title' => 'Apply rules',
+ 'job_config_uc_apply_rules_text' => 'Applies your rules to every imported transaction. Note that this slows the import significantly.',
+ 'job_config_uc_specifics_title' => 'Bank-specific options',
+ 'job_config_uc_specifics_txt' => 'Some banks deliver badly formatted files. Firefly III can fix those automatically. If your bank delivers such files but it\'s not listed here, please open an issue on GitHub.',
+ 'job_config_uc_submit' => 'Continue',
+ 'invalid_import_account' => 'You have selected an invalid account to import into.',
+ // job configuration for Spectre:
+ 'job_config_spectre_login_title' => 'Choose your login',
+ 'job_config_spectre_login_text' => 'Firefly III has found :count existing login(s) in your Spectre account. Which one would you like to use to import from?',
+ 'spectre_login_status_active' => 'Active',
+ 'spectre_login_status_inactive' => 'Inactive',
+ 'spectre_login_status_disabled' => 'Disabled',
+ 'spectre_login_new_login' => 'Login with another bank, or one of these banks with different credentials.',
+ 'job_config_spectre_accounts_title' => 'Select accounts to import from',
+ 'job_config_spectre_accounts_text' => 'You have selected ":name" (:country). You have :count account(s) available from this provider. Please select the Firefly III asset account(s) where the transactions from these accounts should be stored. Remember, in order to import data both the Firefly III account and the ":name"-account must have the same currency.',
+ 'spectre_no_supported_accounts' => 'You cannot import from this account due to a currency mismatch.',
+ 'spectre_do_not_import' => '(do not import)',
+ 'spectre_no_mapping' => 'It seems you have not selected any accounts to import from.',
+ 'imported_from_account' => 'Imported from ":account"',
+ 'spectre_account_with_number' => 'Account :number',
+ // job configuration for bunq:
+ 'job_config_bunq_accounts_title' => 'bunq accounts',
+ 'job_config_bunq_accounts_text' => 'These are the accounts associated with your bunq account. Please select the accounts from which you want to import, and in which account the transactions must be imported.',
+ 'bunq_no_mapping' => 'It seems you have not selected any accounts.',
+ 'should_download_config' => 'You should download the configuration file for this job. This will make future imports way easier.',
+ 'share_config_file' => 'If you have imported data from a public bank, you should share your configuration file so it will be easy for other users to import their data. Sharing your configuration file will not expose your financial details.',
+
+ // keys from "extra" array:
+ 'spectre_extra_key_iban' => 'IBAN',
+ 'spectre_extra_key_swift' => 'SWIFT',
+ 'spectre_extra_key_status' => 'Status',
+ 'spectre_extra_key_card_type' => 'Card type',
+ 'spectre_extra_key_account_name' => 'Account name',
+ 'spectre_extra_key_client_name' => 'Client name',
+ 'spectre_extra_key_account_number' => 'Account number',
+ 'spectre_extra_key_blocked_amount' => 'Blocked amount',
+ 'spectre_extra_key_available_amount' => 'Available amount',
+ 'spectre_extra_key_credit_limit' => 'Credit limit',
+ 'spectre_extra_key_interest_rate' => 'Interest rate',
+ 'spectre_extra_key_expiry_date' => 'Expiry date',
+ 'spectre_extra_key_open_date' => 'Open date',
+ 'spectre_extra_key_current_time' => 'Current time',
+ 'spectre_extra_key_current_date' => 'Current date',
+ 'spectre_extra_key_cards' => 'Cards',
+ 'spectre_extra_key_units' => 'Units',
+ 'spectre_extra_key_unit_price' => 'Unit price',
+ 'spectre_extra_key_transactions_count' => 'Transaction count',
+
+ // specifics:
+ 'specific_ing_name' => 'ING NL',
+ 'specific_ing_descr' => 'Create better descriptions in ING exports',
+ 'specific_sns_name' => 'SNS / Volksbank NL',
+ 'specific_sns_descr' => 'Trim quotes from SNS / Volksbank export files',
+ 'specific_abn_name' => 'ABN AMRO NL',
+ 'specific_abn_descr' => 'Fixes potential problems with ABN AMRO files',
+ 'specific_rabo_name' => 'Rabobank NL',
+ 'specific_rabo_descr' => 'Fixes potential problems with Rabobank files',
+ 'specific_pres_name' => 'President\'s Choice Financial CA',
+ 'specific_pres_descr' => 'Fixes potential problems with PC files',
+ // job configuration for file provider (stage: roles)
+ 'job_config_roles_title' => 'Import setup (3/4) - Define each column\'s role',
+ 'job_config_roles_text' => 'Each column in your CSV file contains certain data. Please indicate what kind of data the importer should expect. The option to "map" data means that you will link each entry found in the column to a value in your database. An often mapped column is the column that contains the IBAN of the opposing account. That can be easily matched to IBAN\'s present in your database already.',
+ 'job_config_roles_submit' => 'Continue',
+ 'job_config_roles_column_name' => 'Name of column',
+ 'job_config_roles_column_example' => 'Column example data',
+ 'job_config_roles_column_role' => 'Column data meaning',
+ 'job_config_roles_do_map_value' => 'Map these values',
+ 'job_config_roles_no_example' => 'No example data available',
+ 'job_config_roles_fa_warning' => 'If you mark a column as containing an amount in a foreign currency, you must also set the column that contains which currency it is.',
+ 'job_config_roles_rwarning' => 'At the very least, mark one column as the amount-column. It is advisable to also select a column for the description, date and the opposing account.',
+ 'job_config_roles_colum_count' => 'Column',
+ // job config for the file provider (stage: mapping):
+ 'job_config_map_title' => 'Import setup (4/4) - Connect import data to Firefly III data',
+ 'job_config_map_text' => 'In the following tables, the left value shows you information found in your uploaded file. It is your task to map this value, if possible, to a value already present in your database. Firefly will stick to this mapping. If there is no value to map to, or you do not wish to map the specific value, select nothing.',
+ 'job_config_map_nothing' => 'There is no data present in your file that you can map to existing values. Please press "Start the import" to continue.',
+ 'job_config_field_value' => 'Field value',
+ 'job_config_field_mapped' => 'Mapped to',
+ 'map_do_not_map' => '(nie mapuj)',
+ 'job_config_map_submit' => 'Start the import',
+
+
+ // import status page:
+ 'import_with_key' => 'Import z kluczem \':key\'',
'status_wait_title' => 'Proszę czekać...',
'status_wait_text' => 'To pole za chwilÄ™ zniknie.',
- 'status_fatal_title' => 'Wystąpił błąd krytyczny',
- 'status_fatal_text' => 'Wystąpił błąd krytyczny, którego procedura importu nie może naprawić. Zobacz wyjaśnienie na czerwono poniżej.',
- 'status_fatal_more' => 'Jeśli przekroczono limit czasu, import zostanie zatrzymany w połowie. W przypadku niektórych konfiguracji serwerów, jedynie serwer przestał odpowiadać podczas gdy importowanie nadal działa w tle. Aby to zweryfikować, należy sprawdzić pliki dziennika. Jeśli problem będzie się powtarzał, należy rozważyć Importowanie poprzez konsolę.',
- 'status_ready_title' => 'Import jest gotowy do uruchomienia',
- 'status_ready_text' => 'Import jest gotowy do uruchomienia. Cała konfiguracja, którą musisz wykonać, została wykonana. Proszę pobierz plik konfiguracyjny. Pomoże Ci w imporcie, jeśli nie pójdzie zgodnie z planem. Aby faktycznie uruchomić import, możesz wykonać następujące polecenie w konsoli lub uruchomić importowanie przez przeglądarkę www. W zależności od konfiguracji import przez konsolę daje więcej informacji zwrotnych.',
- 'status_ready_noconfig_text' => 'Import jest gotowy do uruchomienia. Cała konfiguracja, którą musisz wykonać, została wykonana. Aby faktycznie uruchomić import, możesz wykonać następujące polecenie w konsoli lub uruchomić importowanie przez przeglądarkę www. W zależności od konfiguracji import przez konsolę daje więcej informacji zwrotnych.',
- 'status_ready_config' => 'Pobierz konfiguracjÄ™',
- 'status_ready_start' => 'Rozpocznij Importowanie',
- 'status_ready_share' => 'Rozważ pobranie konfiguracji i udostępnienie jej w centrum konfiguracyjnym portali. Umożliwi to innym użytkownikom Firefly III łatwiejsze importowanie plików.',
- 'status_job_new' => 'Zadanie jest zupełnie nowe.',
- 'status_job_configuring' => 'Import jest konfigurowany.',
- 'status_job_configured' => 'Import jest skonfigurowany.',
- 'status_job_running' => 'Import w toku... Proszę czekać..',
- 'status_job_error' => 'Zadanie wygenerowało błąd.',
- 'status_job_finished' => 'Importowanie zostało zakończone!',
'status_running_title' => 'Trwa importowanie',
- 'status_running_placeholder' => 'Proszę czekać na aktualizację...',
- 'status_finished_title' => 'Zakończono procedurę importu',
- 'status_finished_text' => 'Twoje dane zostały zaimportowane.',
- 'status_errors_title' => 'Błędy podczas importowania',
- 'status_errors_single' => 'Wystąpił błąd podczas importowania. Nie wydaje się być krytyczny.',
- 'status_errors_multi' => 'Wystąpiły błędy podczas importowania. Nie wydają się być krytyczne.',
- 'status_bread_crumb' => 'Status importu',
- 'status_sub_title' => 'Status importu',
- 'config_sub_title' => 'Skonfiguruj import',
- 'status_finished_job' => 'Zaimportowane transakcje (:count) znajdujÄ… siÄ™ w tagu :tag.',
- 'status_finished_no_tag' => 'Firefly III nie zaimportował żadnych transakcji z twojego pliku.',
- 'import_with_key' => 'Import z kluczem \':key\'',
+ 'status_job_running' => 'Please wait, running the import...',
+ 'status_job_storing' => 'Please wait, storing data...',
+ 'status_job_rules' => 'Please wait, running rules...',
+ 'status_fatal_title' => 'Fatal error',
+ 'status_fatal_text' => 'The import has suffered from an error it could not recover from. Apologies!',
+ 'status_fatal_more' => 'This (possibly very cryptic) error message is complemented by log files, which you can find on your hard drive, or in the Docker container where you run Firefly III from.',
+ 'status_finished_title' => 'Import finished',
+ 'status_finished_text' => 'The import has finished.',
+ 'finished_with_errors' => 'There were some errors during the import. Please review them carefully.',
+ 'unknown_import_result' => 'Unknown import result',
+ 'result_no_transactions' => 'No transactions have been imported. Perhaps they were all duplicates is simply no transactions where present to be imported. Perhaps the log files can tell you what happened. If you import data regularly, this is normal.',
+ 'result_one_transaction' => 'Exactly one transaction has been imported. It is stored under tag :tag where you can inspect it further.',
+ 'result_many_transactions' => 'Firefly III has imported :count transactions. They are stored under tag :tag where you can inspect them further.',
- // file, upload something
- 'file_upload_title' => 'Konfiguracja importu (1/4) - Prześlij swój plik',
- 'file_upload_text' => 'Ta procedura pomoże Ci importować pliki z twojego banku do Firefly III. Sprawdź stronę pomocy w prawym górnym rogu.',
- 'file_upload_fields' => 'Pola',
- 'file_upload_help' => 'Wybierz swój plik',
- 'file_upload_config_help' => 'Jeśli wcześniej importowałeś dane do Firefly III, możesz posiadać plik konfiguracji, który wstępnie ustawi wartości parametrów konfiguracyjnych za Ciebie. Dla niektórych banków, inni użytkownicy uprzejmie dostarczyli swoje pliki konfiguracji',
- 'file_upload_type_help' => 'Wybierz typ pliku, który będziesz przesyłać',
- 'file_upload_submit' => 'Prześlij pliki',
- // file, upload types
- 'import_file_type_csv' => 'CSV (wartości oddzielone przecinkami)',
+ // general errors and warnings:
+ 'bad_job_status' => 'To access this page, your import job cannot have status ":status".',
- // file, initial config for CSV
- 'csv_initial_title' => 'Konfiguracja importu (2/4) - Podstawowa konfiguracja importu CSV',
- 'csv_initial_text' => 'Aby móc poprawnie zaimportować plik, sprawdź poprawność poniższych opcji.',
- 'csv_initial_box' => 'Podstawowa konfiguracja importu CSV',
- 'csv_initial_box_title' => 'Podstawowe opcje konfiguracji importu CSV',
- 'csv_initial_header_help' => 'Zaznacz to pole, jeśli pierwszy wiersz w pliku CSV to nazwy kolumn.',
- 'csv_initial_date_help' => 'Format daty i czasu w pliku CSV. Format powinien być zgodny z opisem na tej stronie. Wartość domyślna będzie analizować daty, które wyglądają następująco: :dateExample.',
- 'csv_initial_delimiter_help' => 'Wybierz separator pola, który jest używany w pliku wejściowym. Jeśli nie jesteś pewien, przecinek jest najbezpieczniejszym rozwiązaniem.',
- 'csv_initial_import_account_help' => 'Jeśli Twój plik CSV NIE zawiera informacji o Twoich kontach aktywów, użyj tego menu, aby wybrać, do którego konta należą transakcje w pliku CSV.',
- 'csv_initial_submit' => 'Przejdź do kroku 3/4',
-
- // file, new options:
- 'file_apply_rules_title' => 'Zastosuj reguły',
- 'file_apply_rules_description' => 'Zastosuj swoje reguły. Zwróć uwagę, że to znacznie spowalnia importowanie.',
- 'file_match_bills_title' => 'Dopasuj rachunki',
- 'file_match_bills_description' => 'Dopasuj swoje rachunki do nowo utworzonych wypłat. Zwróć uwagę, że to znacznie spowalnia importowanie.',
-
- // file, roles config
- 'csv_roles_title' => 'Konfiguracja importu (3/4) - Zdefiniuj rolę każdej kolumny',
- 'csv_roles_text' => 'Każda kolumna w pliku CSV zawiera określone dane. Proszę wskazać, jakiego rodzaju danych importer powinien oczekiwać. Opcja "mapowania" danych oznacza, że każdy wpis znaleziony w kolumnie zostanie połączony z wartością w bazie danych. Często odwzorowywana kolumna to kolumna zawierająca numer IBAN konta przeciwnego. Można go łatwo dopasować do obecnego numeru IBAN w bazie danych.',
- 'csv_roles_table' => 'Tabela',
- 'csv_roles_column_name' => 'Nazwa kolumny',
- 'csv_roles_column_example' => 'Przykładowe dane kolumny',
- 'csv_roles_column_role' => 'Znaczenie danych w kolumnie',
- 'csv_roles_do_map_value' => 'Zmapuj te wartości',
- 'csv_roles_column' => 'Kolumna',
- 'csv_roles_no_example_data' => 'Brak przykładowych danych',
- 'csv_roles_submit' => 'Przejdź do kroku 4/4',
-
- // not csv, but normal warning
- 'roles_warning' => 'Zaznacz jedną z kolumn jako kolumnę z kwotami. Wskazane jest również wybranie kolumny dla opisu, daty oraz konta przeciwnego.',
- 'foreign_amount_warning' => 'Jeśli zaznaczysz kolumnę jako zawierającą kwotę w obcej walucie, musisz także ustawić kolumnę, która zawiera kod tej waluty.',
-
- // file, map data
- 'file_map_title' => 'Ustawienia importu (4/4) - Połącz dane importu z danymi Firefly III',
- 'file_map_text' => 'W poniższych tabelach lewa wartość pokazuje informacje znalezione w przesłanym pliku. Twoim zadaniem jest zamapowanie tej wartości, jeśli to możliwe, na wartość już obecną w bazie danych. Firefly będzie trzymać się tego mapowania. Jeśli nie ma wartości do odwzorowania lub nie chcesz mapować określonej wartości, nie wybieraj niczego.',
- 'file_map_field_value' => 'Wartość pola',
- 'file_map_field_mapped_to' => 'Zmapowane do',
- 'map_do_not_map' => '(nie mapuj)',
- 'file_map_submit' => 'Rozpocznij import',
- 'file_nothing_to_map' => 'W twoim pliku nie ma danych, które można by odwzorować na istniejące wartości. Naciśnij "Rozpocznij import", aby kontynuować.',
-
- // map things.
+ // column roles for CSV import:
'column__ignore' => '(zignoruj tÄ™ kolumnÄ™)',
'column_account-iban' => 'Konto aktywów (IBAN)',
'column_account-id' => 'ID konta aktywów (z bazy FF3)',
@@ -158,48 +261,4 @@ return [
'column_note' => 'Notatki',
'column_internal-reference' => 'Internal reference',
- // prerequisites
- 'prerequisites' => 'Wymagania',
-
- // bunq
- 'bunq_prerequisites_title' => 'Wymagania wstępne dla importu z bunq',
- 'bunq_prerequisites_text' => 'Aby importować z Bunq, musisz uzyskać klucz API. Możesz to zrobić za pomocą aplikacji. Zwróć uwagę, że funkcja importu z Bunq jest w wersji BETA. Została przetestowana tylko przy użyciu testowej wersji API.',
- 'bunq_prerequisites_text_ip' => 'Bunq musi znać zewnętrzny adres IP Twojego serwera. Firefly III próbował ustalić go używając usługi ipify. Upewnij się, że ten adres IP jest poprawny albo import się nie powiedzie.',
- 'bunq_do_import' => 'Tak, importuj z tego konta',
- 'bunq_accounts_title' => 'Konta Bunq',
- 'bunq_accounts_text' => 'Te konta są powiązane z Twoim kontem Bunq. Wybierz konta, z których chcesz importować transakcje i na które konto mają trafić.',
-
- // Spectre
- 'spectre_title' => 'Importuj za pomocÄ… Spectre',
- 'spectre_prerequisites_title' => 'Wymagania wstępne do importowania za pomocą Spectre',
- 'spectre_prerequisites_text' => 'Aby importować dane za pomocą interfejsu Spectre API (v4), musisz dostarczyć Firefly III dwie sekretne wartości. Można je znaleźć na stronie sekretów.',
- 'spectre_enter_pub_key' => 'Importowanie będzie działać tylko po wpisaniu tego klucza publicznego na stronie zabezpieczeń.',
- 'spectre_accounts_title' => 'Wybierz konta do zaimportowania z',
- 'spectre_accounts_text' => 'Każde konto po lewej stronie zostało znalezione przez Spectre i może zostać zaimportowane do Firefly III. Wybierz konto aktywów, które powinno zawierać dane transakcje. Jeśli nie chcesz importować z żadnego konkretnego konta, usuń zaznaczenie z pola wyboru.',
- 'spectre_do_import' => 'Tak, importuj z tego konta',
- 'spectre_no_supported_accounts' => 'Nie można importować z tego konta z powodu niedopasowania waluty.',
-
- // keys from "extra" array:
- 'spectre_extra_key_iban' => 'IBAN',
- 'spectre_extra_key_swift' => 'Kod SWIFT',
- 'spectre_extra_key_status' => 'Status',
- 'spectre_extra_key_card_type' => 'Typ karty',
- 'spectre_extra_key_account_name' => 'Nazwa konta',
- 'spectre_extra_key_client_name' => 'Nazwa klienta',
- 'spectre_extra_key_account_number' => 'Numer konta',
- 'spectre_extra_key_blocked_amount' => 'Zablokowana kwota',
- 'spectre_extra_key_available_amount' => 'Dostępna kwota',
- 'spectre_extra_key_credit_limit' => 'Limit kredytowy',
- 'spectre_extra_key_interest_rate' => 'Oprocentowanie',
- 'spectre_extra_key_expiry_date' => 'Data wygaśnięcia',
- 'spectre_extra_key_open_date' => 'Data otwarcia',
- 'spectre_extra_key_current_time' => 'Aktualny czas',
- 'spectre_extra_key_current_date' => 'Aktualna data',
- 'spectre_extra_key_cards' => 'Karty',
- 'spectre_extra_key_units' => 'Jednostki',
- 'spectre_extra_key_unit_price' => 'Cena jednostkowa',
- 'spectre_extra_key_transactions_count' => 'Liczba transakcji',
-
- // various other strings:
- 'imported_from_account' => 'Zaimportowane z ":account"',
];
diff --git a/resources/lang/pl_PL/intro.php b/resources/lang/pl_PL/intro.php
index 678cae900d..4691ce970d 100644
--- a/resources/lang/pl_PL/intro.php
+++ b/resources/lang/pl_PL/intro.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
// index
'index_intro' => 'Witamy na stronie domowej Firefly III. Proszę poświęć trochę czasu, aby przejść przez to wprowadzenie, aby poznać sposób działania Firefly III.',
diff --git a/resources/lang/pl_PL/list.php b/resources/lang/pl_PL/list.php
index f1c0f0df46..a18fe7286e 100644
--- a/resources/lang/pl_PL/list.php
+++ b/resources/lang/pl_PL/list.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
'buttons' => 'Przyciski',
'icon' => 'Ikona',
@@ -111,10 +112,15 @@ return [
'sepa-cc' => 'SEPA Clearing Code',
'sepa-ep' => 'SEPA External Purpose',
'sepa-ci' => 'SEPA Creditor Identifier',
+ 'external_id' => 'External ID',
'account_at_bunq' => 'Konto bunq',
'file_name' => 'Nazwa pliku',
'file_size' => 'Rozmiar pliku',
'file_type' => 'Typ pliku',
'attached_to' => 'Dołączony do',
'file_exists' => 'Plik istnieje',
+ 'spectre_bank' => 'Bank',
+ 'spectre_last_use' => 'Last login',
+ 'spectre_status' => 'Status',
+ 'bunq_payment_id' => 'bunq payment ID',
];
diff --git a/resources/lang/pl_PL/pagination.php b/resources/lang/pl_PL/pagination.php
index af92d3252f..a05d28de8a 100644
--- a/resources/lang/pl_PL/pagination.php
+++ b/resources/lang/pl_PL/pagination.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
'previous' => '« Poprzednia',
'next' => 'NastÄ™pna »',
diff --git a/resources/lang/pl_PL/passwords.php b/resources/lang/pl_PL/passwords.php
index 0d9391ebfb..56dbe0f1e0 100644
--- a/resources/lang/pl_PL/passwords.php
+++ b/resources/lang/pl_PL/passwords.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
'password' => 'Hasło musi zawierać przynajmniej 6 znaków i musi się zgadzać z potwierdzeniem.',
'user' => 'Nie możemy znaleźć użytkownika o podanym adresie email.',
diff --git a/resources/lang/pl_PL/validation.php b/resources/lang/pl_PL/validation.php
index d73aa32b3e..0ae9b71c19 100644
--- a/resources/lang/pl_PL/validation.php
+++ b/resources/lang/pl_PL/validation.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
'iban' => 'To nie jest prawidłowy IBAN.',
'source_equals_destination' => 'Konto źródłowe jest równe kontu docelowemu',
@@ -109,7 +110,8 @@ return [
'in_array' => 'Pole :attribute nie istnieje w :other.',
'present' => 'Pole :attribute musi być obecne.',
'amount_zero' => 'Całkowita kwota nie może być zerem',
- 'secure_password' => 'To nie jest bezpieczne hasło. Proszę spróbować ponownie. Aby uzyskać więcej informacji odwiedź https://goo.gl/NCh2tN',
+ 'unique_piggy_bank_for_user' => 'The name of the piggy bank must be unique.',
+ 'secure_password' => 'This is not a secure password. Please try again. For more information, visit http://bit.ly/FF3-password-security',
'attributes' => [
'email' => 'adres e-mail',
'description' => 'opis',
diff --git a/resources/lang/pt_BR/auth.php b/resources/lang/pt_BR/auth.php
index ee4a1c829d..dc7186514c 100644
--- a/resources/lang/pt_BR/auth.php
+++ b/resources/lang/pt_BR/auth.php
@@ -1,9 +1,8 @@
.
*/
-return [
- /*
- |--------------------------------------------------------------------------
- | Authentication Language Lines
- |--------------------------------------------------------------------------
- |
- | The following language lines are used during authentication for various
- | messages that we need to display to the user. You are free to modify
- | these language lines according to your application's requirements.
- |
- */
+declare(strict_types=1);
+return [
'failed' => 'Essas credenciais não correspondem aos nossos registros.',
'throttle' => 'Muitas tentativas de login. Por favor, tente novamente em :seconds segundos.',
];
diff --git a/resources/lang/pt_BR/bank.php b/resources/lang/pt_BR/bank.php
index 8826020cbf..5d00b1e685 100644
--- a/resources/lang/pt_BR/bank.php
+++ b/resources/lang/pt_BR/bank.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
];
diff --git a/resources/lang/pt_BR/breadcrumbs.php b/resources/lang/pt_BR/breadcrumbs.php
index 4f2f721059..793571ed1c 100644
--- a/resources/lang/pt_BR/breadcrumbs.php
+++ b/resources/lang/pt_BR/breadcrumbs.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
'home' => 'InÃcio',
'edit_currency' => 'Editar moeda ":name"',
@@ -41,7 +42,7 @@ return [
'deposit_list' => 'Receitas, renda e depósitos',
'transfer_list' => 'Transferências',
'transfers_list' => 'Transferências',
- 'reconciliation_list' => 'Reconciliação',
+ 'reconciliation_list' => 'Reconciliações',
'create_withdrawal' => 'Criar uma nova retirada',
'create_deposit' => 'Criar um novo depósito',
'create_transfer' => 'Criar nova transferência',
diff --git a/resources/lang/pt_BR/components.php b/resources/lang/pt_BR/components.php
index ec68877f92..2e02694ebe 100644
--- a/resources/lang/pt_BR/components.php
+++ b/resources/lang/pt_BR/components.php
@@ -1,5 +1,4 @@
.
*/
+declare(strict_types=1);
+
return [
// profile
'personal_access_tokens' => 'Tokens de acesso pessoal',
diff --git a/resources/lang/pt_BR/config.php b/resources/lang/pt_BR/config.php
index 10ca3f6f95..ce507e8a05 100644
--- a/resources/lang/pt_BR/config.php
+++ b/resources/lang/pt_BR/config.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
'html_language' => 'pt-br',
'locale' => 'pt-br, pt_BR, pt_BR.utf8, pt_BR.UTF-8',
diff --git a/resources/lang/pt_BR/csv.php b/resources/lang/pt_BR/csv.php
index 622a49202a..aae109a40a 100644
--- a/resources/lang/pt_BR/csv.php
+++ b/resources/lang/pt_BR/csv.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
];
diff --git a/resources/lang/pt_BR/demo.php b/resources/lang/pt_BR/demo.php
index 9d53564571..b6960bda12 100644
--- a/resources/lang/pt_BR/demo.php
+++ b/resources/lang/pt_BR/demo.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
'no_demo_text' => 'Desculpe, não há nenhum texto extra de explicação para esta página.',
'see_help_icon' => 'No entanto, o -Ãcone no canto superior direito pode lhe dizer mais.',
@@ -32,5 +33,5 @@ return [
'currencies-index' => 'Firefly III oferece suporte a várias moedas. Embora o padrão seja o Euro, ela pode ser definida para o dólar americano e muitas outras moedas. Como você pode ver uma pequena seleção de moedas foi incluÃda, mas você pode adicionar suas próprias se desejar. No entanto, alterar a moeda padrão não vai mudar a moeda de transações existentes: Firefly III suporta o uso de várias moedas ao mesmo tempo.',
'transactions-index' => 'Estas despesas, depósitos e transferências não são fantasiosas. Elas foram geradas automaticamente.',
'piggy-banks-index' => 'Como você pode ver, existem três cofrinhos. Use o sinal de mais e menos botões para influenciar a quantidade de dinheiro em cada cofrinho. Clique no nome do cofrinho para ver a administração de cada cofrinho.',
- 'import-index' => 'Sim, qualquer arquivo CSV pode ser importado para Firefly III',
+ 'import-index' => 'Qualquer arquivo CSV pode ser importado para o Firefly III. Importações de dados de bunq e Specter também são suportadas. Outros bancos e agregadores financeiros serão implementados futuramente. Como usuário de demonstração, no entanto, você só pode ver o provedor "falso" em ação. Ele irá gerar transações aleatórias para lhe mostrar como funciona o processo.',
];
diff --git a/resources/lang/pt_BR/firefly.php b/resources/lang/pt_BR/firefly.php
index 39de222884..988bf0b85a 100644
--- a/resources/lang/pt_BR/firefly.php
+++ b/resources/lang/pt_BR/firefly.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
// general stuff:
'close' => 'Fechar',
@@ -179,6 +180,7 @@ return [
'authorization_request_intro' => ':client está pedindo permissão para acessar sua administração financeira. Gostaria de autorizar :client para acessar esses registros?',
'scopes_will_be_able' => 'Esta aplicação será capaz de:',
'button_authorize' => 'Autorizar',
+ 'none_in_select_list' => '(none)',
// check for updates:
'update_check_title' => 'Verificar Atualizações',
@@ -541,7 +543,7 @@ return [
'attachment_deleted' => 'Anexo apagado ":name"',
'attachment_updated' => 'Anexo atualizado ":name"',
'upload_max_file_size' => 'Tamanho máximo do arquivo: :size',
- 'list_all_attachments' => 'List of all attachments',
+ 'list_all_attachments' => 'Lista de todos os anexos',
// transaction index
'title_expenses' => 'Despesas',
@@ -666,6 +668,7 @@ return [
'bill_will_automatch' => 'A fatura será automaticamente vinculada a transações correspondentes',
'skips_over' => 'ignorar',
'bill_store_error' => 'Um erro inesperado ocorreu ao armazenar sua nova fatura. Por favor, verifique os arquivos de log',
+ 'list_inactive_rule' => 'inactive rule',
// accounts:
'details_for_asset' => 'Detalhes para a conta de ativo ":name"',
@@ -801,6 +804,7 @@ return [
'opt_group_savingAsset' => 'Contas de poupança',
'opt_group_sharedAsset' => 'Contas de ativos compartilhadas',
'opt_group_ccAsset' => 'Cartões de crédito',
+ 'opt_group_cashWalletAsset' => 'Cash wallets',
'notes' => 'Notas',
'unknown_journal_error' => 'A transação não pôde ser armazenada. Por favor, verifique os arquivos de log.',
@@ -816,6 +820,7 @@ return [
'language' => 'Idioma',
'new_savings_account' => 'Conta de poupança :bank_name',
'cash_wallet' => 'Carteira de dinheiro',
+ 'currency_not_present' => 'If the currency you normally use is not listed do not worry. You can create your own currencies under Options > Currencies.',
// home page:
'yourAccounts' => 'Suas contas',
@@ -1013,6 +1018,7 @@ return [
'remove_money_from_piggy_title' => 'Retire o dinheiro do cofrinho ":name"',
'add' => 'Adicionar',
'no_money_for_piggy' => 'Você não tem dinheiro para colocar nessa poupança.',
+ 'suggested_savings_per_month' => 'Suggested per month',
'remove' => 'Remover',
'max_amount_add' => 'É a quantidade máxima que você pode adicionar é',
@@ -1148,27 +1154,9 @@ return [
'no_edit_multiple_left' => 'Você não selecionou nenhuma transação válida para editar.',
'cannot_convert_split_journal' => 'Não é possÃvel converter uma transação dividida',
- // import bread crumbs and titles:
- 'import' => 'Importar',
- 'import_data' => 'Importar dados',
- 'import_general_index_file' => 'Importar um arquivo',
- 'import_from_bunq' => 'Importar de bunq',
- 'import_using_spectre' => 'Importar usando Spectre',
- 'import_using_plaid' => 'Importar usando Plaid',
- 'import_config_bread_crumb' => 'Configurar a sua importação',
-
- // import index page:
+ // Import page (general strings only)
'import_index_title' => 'Importar dados para o Firefly III',
- 'import_index_sub_title' => 'Ãndice',
- 'import_general_index_intro' => 'Bem-vindo à rotina de importação do Firefly III. Existem algumas maneiras de importar dados no Firefly III, exibidos aqui como botões.',
- 'upload_error' => 'O arquivo que você enviou não pôde ser processado. Possivelmente trata-se de tipo ou codificação inválidos de arquivo. Os arquivos de log terão mais informações.',
- 'reset_import_settings_title' => 'Redefinir configuração de importação',
- 'reset_import_settings_text' => 'You can use these links to reset your import settings for specific providers. This is useful when bad settings stop you from importing data.',
- 'reset_settings_bunq' => 'Remove bunq API key, local external IP address and bunq related RSA keys.',
- 'reset_settings_spectre' => 'Remove Spectre secrets and ID\'s. This will also remove your Spectre keypair. Remember to update the new one.',
- 'settings_reset_for_bunq' => 'Bunq settings reset.',
- 'settings_reset_for_spectre' => 'Spectre settings reset.',
-
+ 'import_data' => 'Importar dados',
// sandstorm.io errors and messages:
'sandstorm_not_available' => 'Esta função não está disponÃvel quando você está usando o Firefly III dentro de um ambiente Sandstorm.io.',
diff --git a/resources/lang/pt_BR/form.php b/resources/lang/pt_BR/form.php
index aaed0019ec..f31a9d819a 100644
--- a/resources/lang/pt_BR/form.php
+++ b/resources/lang/pt_BR/form.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
// new user:
'bank_name' => 'Nome do banco',
@@ -184,6 +185,13 @@ return [
'blocked' => 'Está bloqueado?',
'blocked_code' => 'Razão para ser reportado',
+ // import
+ 'apply_rules' => 'Apply rules',
+ 'artist' => 'Artist',
+ 'album' => 'Album',
+ 'song' => 'Song',
+
+
// admin
'domain' => 'DomÃnio',
'single_user_mode' => 'Desabilitar registro de usuários',
@@ -203,7 +211,7 @@ return [
'service_secret' => 'Service secret',
'app_secret' => 'App secret',
'app_id' => 'App ID',
- 'secret' => 'Secret',
+ 'secret' => 'Segredo',
'public_key' => 'Chave pública',
'country_code' => 'Código do paÃs',
'provider_code' => 'Banco ou provedor de dados',
diff --git a/resources/lang/pt_BR/import.php b/resources/lang/pt_BR/import.php
index 1c8b8af545..377665273f 100644
--- a/resources/lang/pt_BR/import.php
+++ b/resources/lang/pt_BR/import.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
- // status of import:
+ // ALL breadcrumbs and subtitles:
+ 'index_breadcrumb' => 'Import data into Firefly III',
+ 'prerequisites_breadcrumb_fake' => 'Prerequisites for the fake import provider',
+ 'prerequisites_breadcrumb_spectre' => 'Prerequisites for Spectre',
+ 'prerequisites_breadcrumb_bunq' => 'Prerequisites for bunq',
+ 'job_configuration_breadcrumb' => 'Configuration for ":key"',
+ 'job_status_breadcrumb' => 'Import status for ":key"',
+ 'cannot_create_for_provider' => 'Firefly III cannot create a job for the ":provider"-provider.',
+
+ // index page:
+ 'general_index_title' => 'Import a file',
+ 'general_index_intro' => 'Welcome to Firefly III\'s import routine. There are a few ways of importing data into Firefly III, displayed here as buttons.',
+ // import provider strings (index):
+ 'button_fake' => 'Fake an import',
+ 'button_file' => 'Import a file',
+ 'button_bunq' => 'Import from bunq',
+ 'button_spectre' => 'Import using Spectre',
+ 'button_plaid' => 'Import using Plaid',
+ 'button_yodlee' => 'Import using Yodlee',
+ 'button_quovo' => 'Import using Quovo',
+ // global config box (index)
+ 'global_config_title' => 'Global import configuration',
+ 'global_config_text' => 'In the future, this box will feature preferences that apply to ALL import providers above.',
+ // prerequisites box (index)
+ 'need_prereq_title' => 'Import prerequisites',
+ 'need_prereq_intro' => 'Some import methods need your attention before they can be used. For example, they might require special API keys or application secrets. You can configure them here. The icon indicates if these prerequisites have been met.',
+ 'do_prereq_fake' => 'Prerequisites for the fake provider',
+ 'do_prereq_file' => 'Prerequisites for file imports',
+ 'do_prereq_bunq' => 'Prerequisites for imports from bunq',
+ 'do_prereq_spectre' => 'Prerequisites for imports using Spectre',
+ 'do_prereq_plaid' => 'Prerequisites for imports using Plaid',
+ 'do_prereq_yodlee' => 'Prerequisites for imports using Yodlee',
+ 'do_prereq_quovo' => 'Prerequisites for imports using Quovo',
+ // provider config box (index)
+ 'can_config_title' => 'Import configuration',
+ 'can_config_intro' => 'Some import methods can be configured to your liking. They have extra settings you can tweak.',
+ 'do_config_fake' => 'Configuration for the fake provider',
+ 'do_config_file' => 'Configuration for file imports',
+ 'do_config_bunq' => 'Configuration for bunq imports',
+ 'do_config_spectre' => 'Configuration for imports from Spectre',
+ 'do_config_plaid' => 'Configuration for imports from Plaid',
+ 'do_config_yodlee' => 'Configuration for imports from Yodlee',
+ 'do_config_quovo' => 'Configuration for imports from Quovo',
+
+ // prerequisites:
+ 'prereq_fake_title' => 'Prerequisites for an import from the fake import provider',
+ 'prereq_fake_text' => 'This fake provider requires a fake API key. It must be 32 characters long. You can use this one: 123456789012345678901234567890AA',
+ 'prereq_spectre_title' => 'Prerequisites for an import using the Spectre API',
+ 'prereq_spectre_text' => 'In order to import data using the Spectre API (v4), you must provide Firefly III with two secret values. They can be found on the secrets page.',
+ 'prereq_spectre_pub' => 'Likewise, the Spectre API needs to know the public key you see below. Without it, it will not recognize you. Please enter this public key on your secrets page.',
+ 'prereq_bunq_title' => 'Prerequisites for an import from bunq',
+ 'prereq_bunq_text' => 'In order to import from bunq, you need to obtain an API key. You can do this through the app. Please note that the import function for bunq is in BETA. It has only been tested against the sandbox API.',
+ 'prereq_bunq_ip' => 'bunq requires your externally facing IP address. Firefly III has tried to fill this in using the ipify service. Make sure this IP address is correct, or the import will fail.',
+ // prerequisites success messages:
+ 'prerequisites_saved_for_fake' => 'Fake API key stored successfully!',
+ 'prerequisites_saved_for_spectre' => 'App ID and secret stored!',
+ 'prerequisites_saved_for_bunq' => 'API key and IP stored!',
+
+ // job configuration:
+ 'job_config_apply_rules_title' => 'Job configuration - apply your rules?',
+ 'job_config_apply_rules_text' => 'Once the fake provider has run, your rules can be applied to the transactions. This adds time to the import.',
+ 'job_config_input' => 'Your input',
+ // job configuration for the fake provider:
+ 'job_config_fake_artist_title' => 'Enter album name',
+ 'job_config_fake_artist_text' => 'Many import routines have a few configuration steps you must go through. In the case of the fake import provider, you must answer some weird questions. In this case, enter "David Bowie" to continue.',
+ 'job_config_fake_song_title' => 'Enter song name',
+ 'job_config_fake_song_text' => 'Mention the song "Golden years" to continue with the fake import.',
+ 'job_config_fake_album_title' => 'Enter album name',
+ 'job_config_fake_album_text' => 'Some import routines require extra data halfway through the import. In the case of the fake import provider, you must answer some weird questions. Enter "Station to station" to continue.',
+ // job configuration form the file provider
+ 'job_config_file_upload_title' => 'Import setup (1/4) - Upload your file',
+ 'job_config_file_upload_text' => 'This routine will help you import files from your bank into Firefly III. ',
+ 'job_config_file_upload_help' => 'Select your file. Please make sure the file is UTF-8 encoded.',
+ 'job_config_file_upload_config_help' => 'If you have previously imported data into Firefly III, you may have a configuration file, which will pre-set configuration values for you. For some banks, other users have kindly provided their configuration file',
+ 'job_config_file_upload_type_help' => 'Select the type of file you will upload',
+ 'job_config_file_upload_submit' => 'Upload files',
+ 'import_file_type_csv' => 'CSV (valores separados por vÃrgula)',
+ 'file_not_utf8' => 'The file you have uploaded is not encoded as UTF-8 or ASCII. Firefly III cannot handle such files. Please use Notepad++ or Sublime to convert your file to UTF-8.',
+ 'job_config_uc_title' => 'Import setup (2/4) - Basic file setup',
+ 'job_config_uc_text' => 'To be able to import your file correctly, please validate the options below.',
+ 'job_config_uc_header_help' => 'Check this box if the first row of your CSV file are the column titles.',
+ 'job_config_uc_date_help' => 'Date time format in your file. Follow the format as this page indicates. The default value will parse dates that look like this: :dateExample.',
+ 'job_config_uc_delimiter_help' => 'Choose the field delimiter that is used in your input file. If not sure, comma is the safest option.',
+ 'job_config_uc_account_help' => 'If your file does NOT contain information about your asset account(s), use this dropdown to select to which account the transactions in the file belong to.',
+ 'job_config_uc_apply_rules_title' => 'Apply rules',
+ 'job_config_uc_apply_rules_text' => 'Applies your rules to every imported transaction. Note that this slows the import significantly.',
+ 'job_config_uc_specifics_title' => 'Bank-specific options',
+ 'job_config_uc_specifics_txt' => 'Some banks deliver badly formatted files. Firefly III can fix those automatically. If your bank delivers such files but it\'s not listed here, please open an issue on GitHub.',
+ 'job_config_uc_submit' => 'Continue',
+ 'invalid_import_account' => 'You have selected an invalid account to import into.',
+ // job configuration for Spectre:
+ 'job_config_spectre_login_title' => 'Choose your login',
+ 'job_config_spectre_login_text' => 'Firefly III has found :count existing login(s) in your Spectre account. Which one would you like to use to import from?',
+ 'spectre_login_status_active' => 'Active',
+ 'spectre_login_status_inactive' => 'Inactive',
+ 'spectre_login_status_disabled' => 'Disabled',
+ 'spectre_login_new_login' => 'Login with another bank, or one of these banks with different credentials.',
+ 'job_config_spectre_accounts_title' => 'Select accounts to import from',
+ 'job_config_spectre_accounts_text' => 'You have selected ":name" (:country). You have :count account(s) available from this provider. Please select the Firefly III asset account(s) where the transactions from these accounts should be stored. Remember, in order to import data both the Firefly III account and the ":name"-account must have the same currency.',
+ 'spectre_no_supported_accounts' => 'You cannot import from this account due to a currency mismatch.',
+ 'spectre_do_not_import' => '(do not import)',
+ 'spectre_no_mapping' => 'It seems you have not selected any accounts to import from.',
+ 'imported_from_account' => 'Imported from ":account"',
+ 'spectre_account_with_number' => 'Account :number',
+ // job configuration for bunq:
+ 'job_config_bunq_accounts_title' => 'bunq accounts',
+ 'job_config_bunq_accounts_text' => 'These are the accounts associated with your bunq account. Please select the accounts from which you want to import, and in which account the transactions must be imported.',
+ 'bunq_no_mapping' => 'It seems you have not selected any accounts.',
+ 'should_download_config' => 'You should download the configuration file for this job. This will make future imports way easier.',
+ 'share_config_file' => 'If you have imported data from a public bank, you should share your configuration file so it will be easy for other users to import their data. Sharing your configuration file will not expose your financial details.',
+
+ // keys from "extra" array:
+ 'spectre_extra_key_iban' => 'IBAN',
+ 'spectre_extra_key_swift' => 'SWIFT',
+ 'spectre_extra_key_status' => 'Status',
+ 'spectre_extra_key_card_type' => 'Card type',
+ 'spectre_extra_key_account_name' => 'Account name',
+ 'spectre_extra_key_client_name' => 'Client name',
+ 'spectre_extra_key_account_number' => 'Account number',
+ 'spectre_extra_key_blocked_amount' => 'Blocked amount',
+ 'spectre_extra_key_available_amount' => 'Available amount',
+ 'spectre_extra_key_credit_limit' => 'Credit limit',
+ 'spectre_extra_key_interest_rate' => 'Interest rate',
+ 'spectre_extra_key_expiry_date' => 'Expiry date',
+ 'spectre_extra_key_open_date' => 'Open date',
+ 'spectre_extra_key_current_time' => 'Current time',
+ 'spectre_extra_key_current_date' => 'Current date',
+ 'spectre_extra_key_cards' => 'Cards',
+ 'spectre_extra_key_units' => 'Units',
+ 'spectre_extra_key_unit_price' => 'Unit price',
+ 'spectre_extra_key_transactions_count' => 'Transaction count',
+
+ // specifics:
+ 'specific_ing_name' => 'ING NL',
+ 'specific_ing_descr' => 'Create better descriptions in ING exports',
+ 'specific_sns_name' => 'SNS / Volksbank NL',
+ 'specific_sns_descr' => 'Trim quotes from SNS / Volksbank export files',
+ 'specific_abn_name' => 'ABN AMRO NL',
+ 'specific_abn_descr' => 'Fixes potential problems with ABN AMRO files',
+ 'specific_rabo_name' => 'Rabobank NL',
+ 'specific_rabo_descr' => 'Fixes potential problems with Rabobank files',
+ 'specific_pres_name' => 'President\'s Choice Financial CA',
+ 'specific_pres_descr' => 'Fixes potential problems with PC files',
+ // job configuration for file provider (stage: roles)
+ 'job_config_roles_title' => 'Import setup (3/4) - Define each column\'s role',
+ 'job_config_roles_text' => 'Each column in your CSV file contains certain data. Please indicate what kind of data the importer should expect. The option to "map" data means that you will link each entry found in the column to a value in your database. An often mapped column is the column that contains the IBAN of the opposing account. That can be easily matched to IBAN\'s present in your database already.',
+ 'job_config_roles_submit' => 'Continue',
+ 'job_config_roles_column_name' => 'Name of column',
+ 'job_config_roles_column_example' => 'Column example data',
+ 'job_config_roles_column_role' => 'Column data meaning',
+ 'job_config_roles_do_map_value' => 'Map these values',
+ 'job_config_roles_no_example' => 'No example data available',
+ 'job_config_roles_fa_warning' => 'If you mark a column as containing an amount in a foreign currency, you must also set the column that contains which currency it is.',
+ 'job_config_roles_rwarning' => 'At the very least, mark one column as the amount-column. It is advisable to also select a column for the description, date and the opposing account.',
+ 'job_config_roles_colum_count' => 'Column',
+ // job config for the file provider (stage: mapping):
+ 'job_config_map_title' => 'Import setup (4/4) - Connect import data to Firefly III data',
+ 'job_config_map_text' => 'In the following tables, the left value shows you information found in your uploaded file. It is your task to map this value, if possible, to a value already present in your database. Firefly will stick to this mapping. If there is no value to map to, or you do not wish to map the specific value, select nothing.',
+ 'job_config_map_nothing' => 'There is no data present in your file that you can map to existing values. Please press "Start the import" to continue.',
+ 'job_config_field_value' => 'Field value',
+ 'job_config_field_mapped' => 'Mapped to',
+ 'map_do_not_map' => '(não mapear)',
+ 'job_config_map_submit' => 'Start the import',
+
+
+ // import status page:
+ 'import_with_key' => 'Importar com a chave \':key\'',
'status_wait_title' => 'Por favor espere...',
'status_wait_text' => 'Esta caixa desaparecerá em um instante.',
- 'status_fatal_title' => 'Ocorreu um erro fatal',
- 'status_fatal_text' => 'Ocorreu um erro fatal, cuja rotina de importação não pode se recuperar. Veja a explicação em vermelho abaixo.',
- 'status_fatal_more' => 'Se o erro for um tempo limite, a importação terá parado a meio caminho. Para algumas configurações do servidor, é apenas o servidor que parou enquanto a importação continua em execução em segundo plano. Para verificar isso, confira os arquivos de log. Se o problema persistir, considere importação na linha de comando em vez disso.',
- 'status_ready_title' => 'A importação está pronta para começar',
- 'status_ready_text' => 'A importação está pronta para começar. Toda a configuração que você precisava fazer foi feita. Faça o download do arquivo de configuração. Isso irá ajudá-lo com a importação se não for como planejado. Para realmente executar a importação, você pode executar o seguinte comando no seu console ou executar a importação baseada na web. Dependendo da sua configuração, a importação do console lhe dará mais comentários.',
- 'status_ready_noconfig_text' => 'A importação está pronta para começar. Toda a configuração que você precisava fazer foi feita. Para realmente executar a importação, você pode executar o seguinte comando no seu console ou executar a importação baseada na web. Dependendo da sua configuração, a importação do console lhe dará mais comentários.',
- 'status_ready_config' => 'Download da configuração',
- 'status_ready_start' => 'Iniciar a importação',
- 'status_ready_share' => 'Por favor, considere baixar sua configuração e compartilhá-la no centro de configuração de importação. Isso permitirá que outros usuários do Firefly III importem seus arquivos mais facilmente.',
- 'status_job_new' => 'O trabalho é novo.',
- 'status_job_configuring' => 'A importação está sendo configurada.',
- 'status_job_configured' => 'A importação está configurada.',
- 'status_job_running' => 'A importação está em execução.. Aguarde..',
- 'status_job_error' => 'O trabalho gerou um erro.',
- 'status_job_finished' => 'A importação terminou!',
'status_running_title' => 'A importação está em execução',
- 'status_running_placeholder' => 'Por favor, aguarde uma atualização...',
- 'status_finished_title' => 'Rotina de importação concluÃda',
- 'status_finished_text' => 'A rotina de importação importou seus dados.',
- 'status_errors_title' => 'Erros durante a importação',
- 'status_errors_single' => 'Ocorreu um erro durante a importação. Não parece ser fatal.',
- 'status_errors_multi' => 'Alguns erros ocorreram durante a importação. Estes não parecem ser fatais.',
- 'status_bread_crumb' => 'Status de importação',
- 'status_sub_title' => 'Status de importação',
- 'config_sub_title' => 'Configurar a sua importação',
- 'status_finished_job' => 'As transações de :count importadas podem ser encontradas na tag :tag.',
- 'status_finished_no_tag' => 'Firefly III não coletou nenhuma transação de seu arquivo de importação.',
- 'import_with_key' => 'Importar com a chave \':key\'',
+ 'status_job_running' => 'Please wait, running the import...',
+ 'status_job_storing' => 'Please wait, storing data...',
+ 'status_job_rules' => 'Please wait, running rules...',
+ 'status_fatal_title' => 'Fatal error',
+ 'status_fatal_text' => 'The import has suffered from an error it could not recover from. Apologies!',
+ 'status_fatal_more' => 'This (possibly very cryptic) error message is complemented by log files, which you can find on your hard drive, or in the Docker container where you run Firefly III from.',
+ 'status_finished_title' => 'Import finished',
+ 'status_finished_text' => 'The import has finished.',
+ 'finished_with_errors' => 'There were some errors during the import. Please review them carefully.',
+ 'unknown_import_result' => 'Unknown import result',
+ 'result_no_transactions' => 'No transactions have been imported. Perhaps they were all duplicates is simply no transactions where present to be imported. Perhaps the log files can tell you what happened. If you import data regularly, this is normal.',
+ 'result_one_transaction' => 'Exactly one transaction has been imported. It is stored under tag :tag where you can inspect it further.',
+ 'result_many_transactions' => 'Firefly III has imported :count transactions. They are stored under tag :tag where you can inspect them further.',
- // file, upload something
- 'file_upload_title' => 'Configuração de importação (1/4) - Carregar seu arquivo',
- 'file_upload_text' => 'Esta rotina irá ajudá-lo a importar arquivos do seu banco para o Firefly III. Por favor, confira as páginas de ajuda no canto superior direito.',
- 'file_upload_fields' => 'Campos',
- 'file_upload_help' => 'Selecione seu arquivo',
- 'file_upload_config_help' => 'Se você já importou dados no Firefly III, você pode ter um arquivo de configuração, que irá predefinir os valores de configuração para você. Para alguns bancos, outros usuários forneceram gentilmente o arquivo arquivo de configuração',
- 'file_upload_type_help' => 'Selecione o tipo de arquivo que você fará o upload',
- 'file_upload_submit' => 'Upload de arquivos',
- // file, upload types
- 'import_file_type_csv' => 'CSV (valores separados por vÃrgula)',
+ // general errors and warnings:
+ 'bad_job_status' => 'To access this page, your import job cannot have status ":status".',
- // file, initial config for CSV
- 'csv_initial_title' => 'Configuração de importação (2/4) - Configuração de importação CSV básica',
- 'csv_initial_text' => 'Para ser capaz de importar o arquivo corretamente, por favor valide as opções abaixo.',
- 'csv_initial_box' => 'Configuração básica de importação CSV',
- 'csv_initial_box_title' => 'Opções básicas de configuração de importação CSV',
- 'csv_initial_header_help' => 'Marque esta caixa se a primeira linha do seu arquivo CSV for os tÃtulos das colunas.',
- 'csv_initial_date_help' => 'Formato de data e hora em seu CSV. Siga o formato como indica esta página. O valor padrão analisará datas que se parecem com isso: :dateExample.',
- 'csv_initial_delimiter_help' => 'Escolha o delimitador de campo que é usado em seu arquivo de entrada. Se não tiver certeza, a vÃrgula é a opção mais segura.',
- 'csv_initial_import_account_help' => 'Se o seu arquivo CSV NÃO contém informações sobre sua(s) conta(s) de ativo(s), use este combobox para selecionar para qual conta pertencem as transações no CSV.',
- 'csv_initial_submit' => 'Continue com o passo 3/4',
-
- // file, new options:
- 'file_apply_rules_title' => 'Aplicar regras',
- 'file_apply_rules_description' => 'Aplique suas regras. Observe que isso reduz significativamente a velocidade da importação.',
- 'file_match_bills_title' => 'Correspondência de contas',
- 'file_match_bills_description' => 'Combine suas contas para retiradas recém-criadas. Observe que isso diminui significativamente a velocidade de importação.',
-
- // file, roles config
- 'csv_roles_title' => 'Configuração de importação (3/4) - Definir o papel de cada coluna',
- 'csv_roles_text' => 'Cada coluna no seu arquivo CSV contém certos dados. Por favor, indique que tipo de dados, o importador deve esperar. A opção "mapear" dados significa que você vai ligar cada entrada encontrada na coluna para um valor em seu banco de dados. Uma coluna mapeada muitas vezes é a coluna que contém o IBAN da conta oposta. Isso pode ser facilmente combinado para o IBAN já presente em seu banco de dados.',
- 'csv_roles_table' => 'Tabela',
- 'csv_roles_column_name' => 'Nome da coluna',
- 'csv_roles_column_example' => 'Dados de exemplo da coluna',
- 'csv_roles_column_role' => 'Significado dos dados da coluna',
- 'csv_roles_do_map_value' => 'Mapear estes valores',
- 'csv_roles_column' => 'Coluna',
- 'csv_roles_no_example_data' => 'Não há dados de exemplo disponÃveis',
- 'csv_roles_submit' => 'Continue com o passo 4/4',
-
- // not csv, but normal warning
- 'roles_warning' => 'No mÃnimo, marque uma coluna como a coluna de quantidade. É aconselhável também selecionar uma coluna para a descrição, data e a conta oposta.',
- 'foreign_amount_warning' => 'Se você marcar uma coluna como contendo um valor em uma moeda estrangeira, você também deve definir a coluna que contém qual moeda é.',
-
- // file, map data
- 'file_map_title' => 'Configuração de importação (4/4) - Conecte dados de importação aos dados do Firefly III',
- 'file_map_text' => 'Nas tabelas a seguir, o valor à esquerda mostra informações encontradas no seu arquivo carregado. É sua tarefa mapear esse valor, se possÃvel, para um valor já presente em seu banco de dados. O Firefly vai se ater a esse mapeamento. Se não há nenhum valor para mapear, ou não quer mapear o valor especÃfico, não selecione nada.',
- 'file_map_field_value' => 'Valor do campo',
- 'file_map_field_mapped_to' => 'Mapeado para',
- 'map_do_not_map' => '(não mapear)',
- 'file_map_submit' => 'Iniciar a importação',
- 'file_nothing_to_map' => 'Não há dados presentes no seu arquivo que você possa mapear para os valores existentes. Pressione "Iniciar a importação" para continuar.',
-
- // map things.
+ // column roles for CSV import:
'column__ignore' => '(ignorar esta coluna)',
'column_account-iban' => 'Conta de Ativo (IBAN)',
'column_account-id' => 'ID da Conta de Ativo (correspondente FF3)',
@@ -158,48 +261,4 @@ return [
'column_note' => 'Nota(s)',
'column_internal-reference' => 'Referência interna',
- // prerequisites
- 'prerequisites' => 'Pré-requisitos',
-
- // bunq
- 'bunq_prerequisites_title' => 'Pré-requisitos para uma importação de bunq',
- 'bunq_prerequisites_text' => 'Para importar do bunq, você precisa obter uma chave de API. Você pode fazer isso através do aplicativo. Por favor, note que a função de importação para bunq está em BETA. Só foi testado em relação à API do sandbox.',
- 'bunq_prerequisites_text_ip' => 'Bunq requer seu endereço IP externo. O Firefly III tentou preencher isso usando o serviço ipify. Certifique-se de que esse endereço IP esteja correto ou a importação falhará.',
- 'bunq_do_import' => 'Sim, importe desta conta',
- 'bunq_accounts_title' => 'Contas Bunq',
- 'bunq_accounts_text' => 'Estas são as contas associadas à sua conta bunq. Por favor, selecione as contas das quais você deseja importar e em qual conta as transações devem ser importadas.',
-
- // Spectre
- 'spectre_title' => 'Importar usando Spectre',
- 'spectre_prerequisites_title' => 'Pré-requisitos para uma importação usando Spectre',
- 'spectre_prerequisites_text' => 'In order to import data using the Spectre API (v4), you must provide Firefly III with two secret values. They can be found on the secrets page.',
- 'spectre_enter_pub_key' => 'The import will only work when you enter this public key on your secrets page.',
- 'spectre_accounts_title' => 'Selecione as contas a serem importadas',
- 'spectre_accounts_text' => 'Cada conta à esquerda abaixo foi encontrada pela Spectre e pode ser importada para Firefly III. Por favor selecione a conta de ativo que deve armazenar as transações. Se você não deseja importar de qualquer conta especÃfica, desmarque a caixa de seleção.',
- 'spectre_do_import' => 'Sim, importe a partir desta conta',
- 'spectre_no_supported_accounts' => 'You cannot import from this account due to a currency mismatch.',
-
- // keys from "extra" array:
- 'spectre_extra_key_iban' => 'IBAN',
- 'spectre_extra_key_swift' => 'SWIFT',
- 'spectre_extra_key_status' => 'Status',
- 'spectre_extra_key_card_type' => 'Tipo de Cartão',
- 'spectre_extra_key_account_name' => 'Nome da Conta',
- 'spectre_extra_key_client_name' => 'Nome do cliente',
- 'spectre_extra_key_account_number' => 'Número da conta',
- 'spectre_extra_key_blocked_amount' => 'Montante bloqueado',
- 'spectre_extra_key_available_amount' => 'Montante disponÃvel',
- 'spectre_extra_key_credit_limit' => 'Limite de crédito',
- 'spectre_extra_key_interest_rate' => 'Taxa de juros',
- 'spectre_extra_key_expiry_date' => 'Data de vencimento',
- 'spectre_extra_key_open_date' => 'Data de abertura',
- 'spectre_extra_key_current_time' => 'Hora atual',
- 'spectre_extra_key_current_date' => 'Data atual',
- 'spectre_extra_key_cards' => 'Cartões',
- 'spectre_extra_key_units' => 'Unidades',
- 'spectre_extra_key_unit_price' => 'Preço unitário',
- 'spectre_extra_key_transactions_count' => 'Contagem de transações',
-
- // various other strings:
- 'imported_from_account' => 'Importado de ":account"',
];
diff --git a/resources/lang/pt_BR/intro.php b/resources/lang/pt_BR/intro.php
index 3881118023..48b99c3d4d 100644
--- a/resources/lang/pt_BR/intro.php
+++ b/resources/lang/pt_BR/intro.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
// index
'index_intro' => 'Bem-vindo à página de inicial do Firefly III. Por favor, aproveite esta introdução para verificar como funciona o Firefly III.',
diff --git a/resources/lang/pt_BR/list.php b/resources/lang/pt_BR/list.php
index a6f816549b..f65a5eee64 100644
--- a/resources/lang/pt_BR/list.php
+++ b/resources/lang/pt_BR/list.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
'buttons' => 'Botões',
'icon' => 'Ãcone',
@@ -104,17 +105,22 @@ return [
'reconcile' => 'Pago',
'account_on_spectre' => 'Conta (Spectre)',
'do_import' => 'Importar desta conta',
- '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',
- 'account_at_bunq' => 'Account with bunq',
- 'file_name' => 'File name',
- 'file_size' => 'File size',
- 'file_type' => 'File type',
- 'attached_to' => 'Attached to',
- 'file_exists' => 'File exists',
+ 'sepa-ct-id' => 'SEPA Identificador end-to-end',
+ 'sepa-ct-op' => 'SEPA Identificador de conta de contrária',
+ 'sepa-db' => 'SEPA Identificador de Mandato',
+ 'sepa-country' => 'SEPA PaÃs',
+ 'sepa-cc' => 'SEPA Código de Compensação',
+ 'sepa-ep' => 'SEPA Finalidade Externa',
+ 'sepa-ci' => 'SEPA Identificador do Credor',
+ 'external_id' => 'External ID',
+ 'account_at_bunq' => 'Loja com bunq',
+ 'file_name' => 'Nome do arquivo',
+ 'file_size' => 'Tamanho do Arquivo',
+ 'file_type' => 'Tipo do arquivo',
+ 'attached_to' => 'Anexado a',
+ 'file_exists' => 'Arquivo já existe',
+ 'spectre_bank' => 'Bank',
+ 'spectre_last_use' => 'Last login',
+ 'spectre_status' => 'Status',
+ 'bunq_payment_id' => 'bunq payment ID',
];
diff --git a/resources/lang/pt_BR/pagination.php b/resources/lang/pt_BR/pagination.php
index 4a6ef00749..af96c3851f 100644
--- a/resources/lang/pt_BR/pagination.php
+++ b/resources/lang/pt_BR/pagination.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
'previous' => '« Anterior',
'next' => 'Próximo »',
diff --git a/resources/lang/pt_BR/passwords.php b/resources/lang/pt_BR/passwords.php
index 9bc624014f..d5e1ac0558 100644
--- a/resources/lang/pt_BR/passwords.php
+++ b/resources/lang/pt_BR/passwords.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
'password' => 'A senha precisa ter no mÃnimo seis caracteres e tem que ser igual à confirmação de senha.',
'user' => 'Não foi possÃvel encontrar o usuário com este e-mail.',
diff --git a/resources/lang/pt_BR/validation.php b/resources/lang/pt_BR/validation.php
index 3f019d5122..841f7c2d55 100644
--- a/resources/lang/pt_BR/validation.php
+++ b/resources/lang/pt_BR/validation.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
'iban' => 'Este não é um válido IBAN.',
- 'source_equals_destination' => 'The source account equals the destination account',
+ 'source_equals_destination' => 'A conta de origem é igual à conta de destino',
'unique_account_number_for_user' => 'Parece que este número de conta já está em uso.',
- 'unique_iban_for_user' => 'It looks like this IBAN is already in use.',
+ 'unique_iban_for_user' => 'Parece que este IBAN já está em uso.',
'deleted_user' => 'Devido a restrições de segurança, você não pode registrar usando este endereço de e-mail.',
'rule_trigger_value' => 'Este valor é inválido para o disparo selecionado.',
'rule_action_value' => 'Este valor é inválido para a ação selecionada.',
@@ -109,7 +110,8 @@ return [
'in_array' => 'O campo :attribute não existe em :other.',
'present' => 'O campo :attribute deve estar presente.',
'amount_zero' => 'A quantidade total não pode ser zero',
- 'secure_password' => 'Esta não é uma senha segura. Por favor, tente novamente. Para mais informações, visite https://goo.gl/NCh2tN',
+ 'unique_piggy_bank_for_user' => 'The name of the piggy bank must be unique.',
+ 'secure_password' => 'This is not a secure password. Please try again. For more information, visit http://bit.ly/FF3-password-security',
'attributes' => [
'email' => 'endereço de e-mail',
'description' => 'descrição',
diff --git a/resources/lang/ru_RU/auth.php b/resources/lang/ru_RU/auth.php
index 1d79c2f2d3..9dbede848c 100644
--- a/resources/lang/ru_RU/auth.php
+++ b/resources/lang/ru_RU/auth.php
@@ -1,9 +1,8 @@
.
*/
-return [
- /*
- |--------------------------------------------------------------------------
- | Authentication Language Lines
- |--------------------------------------------------------------------------
- |
- | The following language lines are used during authentication for various
- | messages that we need to display to the user. You are free to modify
- | these language lines according to your application's requirements.
- |
- */
+declare(strict_types=1);
+return [
'failed' => 'Ðеправильный Ð°Ð´Ñ€ÐµÑ Ñлектронной почты или пароль.',
'throttle' => 'Слишком много попыток входа. ПожалуйÑта, попробуйте Ñнова через :seconds Ñекунд.',
];
diff --git a/resources/lang/ru_RU/bank.php b/resources/lang/ru_RU/bank.php
index 8826020cbf..5d00b1e685 100644
--- a/resources/lang/ru_RU/bank.php
+++ b/resources/lang/ru_RU/bank.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
];
diff --git a/resources/lang/ru_RU/breadcrumbs.php b/resources/lang/ru_RU/breadcrumbs.php
index 0ef4f707f2..41a0facb3a 100644
--- a/resources/lang/ru_RU/breadcrumbs.php
+++ b/resources/lang/ru_RU/breadcrumbs.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
'home' => 'ГлавнаÑ',
'edit_currency' => 'Редактирование валюты ":name"',
diff --git a/resources/lang/ru_RU/components.php b/resources/lang/ru_RU/components.php
index 2bf8a35763..8f542b54d8 100644
--- a/resources/lang/ru_RU/components.php
+++ b/resources/lang/ru_RU/components.php
@@ -1,5 +1,4 @@
.
*/
+declare(strict_types=1);
+
return [
// profile
'personal_access_tokens' => 'ПерÑональный токен Ð´Ð»Ñ Ð´Ð¾Ñтупа',
diff --git a/resources/lang/ru_RU/config.php b/resources/lang/ru_RU/config.php
index 65d4328335..a524e3644c 100644
--- a/resources/lang/ru_RU/config.php
+++ b/resources/lang/ru_RU/config.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
'html_language' => 'ru',
'locale' => 'ru, Russian, ru_RU, ru_RU.utf8, ru_RU.UTF-8',
diff --git a/resources/lang/ru_RU/csv.php b/resources/lang/ru_RU/csv.php
index 622a49202a..aae109a40a 100644
--- a/resources/lang/ru_RU/csv.php
+++ b/resources/lang/ru_RU/csv.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
];
diff --git a/resources/lang/ru_RU/demo.php b/resources/lang/ru_RU/demo.php
index 45ef6068bf..293ba441f0 100644
--- a/resources/lang/ru_RU/demo.php
+++ b/resources/lang/ru_RU/demo.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
'no_demo_text' => 'Извините, но Ð´Ð»Ñ Ñтой Ñтраницы нет дополнительного поÑÑнениÑ.',
'see_help_icon' => 'ВоÑпользуйтеÑÑŒ значком в правом верхнем углу, чтобы узнать больше.',
@@ -32,5 +33,5 @@ return [
'currencies-index' => 'Firefly III поддерживает неÑколько валют. Ð¥Ð¾Ñ‚Ñ Ð¿Ð¾ умолчанию иÑпользуетÑÑ Ð•Ð²Ñ€Ð¾, вы можете Ñделать оÑновной валютой доллары СШРили любую другую валюту. Как вы видите, неÑколько валют уже еÑть в ÑпиÑке, но вы можете добавить любую другую, еÑли Ñто требуетÑÑ. Обратите внимание, что выбор новой валюты по умолчанию не повлиÑет на уже ÑущеÑтвующие транзакции: Firefly III поддерживает одновременное иÑпользование неÑкольких валют.',
'transactions-index' => 'Ðти раÑходы, доходы и переводы не очень интереÑны. Они были Ñозданы автоматичеÑки.',
'piggy-banks-index' => 'Как вы можете видеть, здеÑÑŒ еÑть три копилки. ИÑпользуйте кнопки «плюÑ» и «минуÑ», чтобы влиÑть на количеÑтво денег в каждой копилке. Ðажмите название копилки, чтобы увидеть её наÑтройки.',
- 'import-index' => 'Конечно, любой CSV-файл может быть импортирован в Firefly III',
+ 'import-index' => 'Ð’ Firefly III можно импортировать любой CSV-файл. Также поддерживаетÑÑ Ð¸Ð¼Ð¿Ð¾Ñ€Ñ‚ данных из bunq и Spectre. Другие банки и финанÑовые агрегаторы будут реализованы в будущем. Однако, как демо-пользователь, вы можете видеть только как работает «поддельный»-провайдер. Он будет генерировать некоторые Ñлучайные транзакции, чтобы показать вам, как работает Ñтот процеÑÑ.',
];
diff --git a/resources/lang/ru_RU/firefly.php b/resources/lang/ru_RU/firefly.php
index 0d0352cf61..382410ca5c 100644
--- a/resources/lang/ru_RU/firefly.php
+++ b/resources/lang/ru_RU/firefly.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
// general stuff:
'close' => 'Закрыть',
@@ -179,6 +180,7 @@ return [
'authorization_request_intro' => ':client запрашивает доÑтуп к управлению вашими финанÑами. Ð’Ñ‹ хотите разрешить :client доÑтуп к Ñтой информации?',
'scopes_will_be_able' => 'Ðто приложение будет иметь возможноÑть:',
'button_authorize' => 'ÐвторизациÑ',
+ 'none_in_select_list' => '(нет)',
// check for updates:
'update_check_title' => 'Проверить обновлениÑ',
@@ -666,6 +668,7 @@ return [
'bill_will_automatch' => 'Счёт будет автоматичеÑки ÑвÑзан Ñ Ð¿Ð¾Ð´Ñ…Ð¾Ð´Ñщими транзакциÑми',
'skips_over' => 'пропуÑтить',
'bill_store_error' => 'При Ñоздании вашего нового Ñчёта на оплату произошла Ð½ÐµÐ¾Ð¶Ð¸Ð´Ð°Ð½Ð½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ°. ПожалуйÑта, проверьте log-файлы',
+ 'list_inactive_rule' => 'неактивное правило',
// accounts:
'details_for_asset' => 'Детали по оÑновному Ñчёту ":name"',
@@ -801,6 +804,7 @@ return [
'opt_group_savingAsset' => 'Сберегательные Ñчета',
'opt_group_sharedAsset' => 'Общие оÑновные Ñчета',
'opt_group_ccAsset' => 'Кредитные карты',
+ 'opt_group_cashWalletAsset' => 'Кошельки Ñ Ð½Ð°Ð»Ð¸Ñ‡Ð½Ñ‹Ð¼Ð¸',
'notes' => 'Заметки',
'unknown_journal_error' => 'Ðе удалоÑÑŒ Ñохранить транзакцию. ПожалуйÑта, проверьте log-файлы.',
@@ -816,6 +820,7 @@ return [
'language' => 'Язык',
'new_savings_account' => 'Ñберегательный Ñчёт в :bank_name',
'cash_wallet' => 'Кошелёк Ñ Ð½Ð°Ð»Ð¸Ñ‡Ð½Ñ‹Ð¼Ð¸',
+ 'currency_not_present' => 'If the currency you normally use is not listed do not worry. You can create your own currencies under Options > Currencies.',
// home page:
'yourAccounts' => 'Ваши Ñчета',
@@ -1013,6 +1018,7 @@ return [
'remove_money_from_piggy_title' => 'Удалить деньги из копилки ":name"',
'add' => 'Добавить',
'no_money_for_piggy' => 'У Ð²Ð°Ñ Ð½ÐµÑ‚ денег, чтобы положить в Ñтот копилку.',
+ 'suggested_savings_per_month' => 'Suggested per month',
'remove' => 'Удалить',
'max_amount_add' => 'МакÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ Ñумма, которую вы можете добавить:',
@@ -1148,27 +1154,9 @@ return [
'no_edit_multiple_left' => 'Ð’Ñ‹ выбрали Ð´Ð»Ñ Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð½ÐµÐºÐ¾Ñ€Ñ€ÐµÐºÑ‚Ð½ÑƒÑŽ транзакцию.',
'cannot_convert_split_journal' => 'Ðевозможно преобразовать раздельную транзакцию',
- // import bread crumbs and titles:
- 'import' => 'Импорт',
- 'import_data' => 'Импорт данных',
- 'import_general_index_file' => 'Импортировать файл',
- 'import_from_bunq' => 'Импорт из bunq',
- 'import_using_spectre' => 'Импорт Ñ Ð¸Ñпользованием Spectre',
- 'import_using_plaid' => 'Импорт Ñ Ð¸Ñпользованием Plaid',
- 'import_config_bread_crumb' => 'ÐаÑтройте Ñвой импорт',
-
- // import index page:
+ // Import page (general strings only)
'import_index_title' => 'Импорт данных в Firefly III',
- 'import_index_sub_title' => 'Ð“Ð»Ð°Ð²Ð½Ð°Ñ Ñтраница',
- 'import_general_index_intro' => 'Добро пожаловать в инÑтрумент импорта Firefly III. СущеÑтвует неÑколько ÑпоÑобов импорта данных в Firefly III, отображаемых здеÑÑŒ в виде кнопок.',
- 'upload_error' => 'Ðевозможно обработать загруженный вами файл. Возможно, Ñто неправильный тип файла или кодировка. Ð”Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ ÑодержитÑÑ Ð² log-файлах.',
- 'reset_import_settings_title' => 'СброÑить наÑтройки импорта',
- 'reset_import_settings_text' => 'Ð’Ñ‹ можете иÑпользовать Ñти ÑÑылки Ð´Ð»Ñ ÑброÑа наÑтроек импорта Ð´Ð»Ñ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð½Ñ‹Ñ… поÑтавщиков. Ðто полезно, когда плохие наÑтройки не позволÑÑŽÑ‚ вам импортировать данные.',
- 'reset_settings_bunq' => 'Удалите ключ API bunq, локальный внешний IP-Ð°Ð´Ñ€ÐµÑ Ð¸ ключи RSA, ÑвÑзанные Ñ bunq.',
- 'reset_settings_spectre' => 'Удалить ID клиента Spectre и Ñекретные ключи. Также будет удалён ваш Spectre keypair. Ðе забудьте обновить его.',
- 'settings_reset_for_bunq' => 'Ð¡Ð±Ñ€Ð¾Ñ Ð½Ð°Ñтроек Bunq.',
- 'settings_reset_for_spectre' => 'Ð¡Ð±Ñ€Ð¾Ñ Ð½Ð°Ñтроек Spectre.',
-
+ 'import_data' => 'Импорт данных',
// sandstorm.io errors and messages:
'sandstorm_not_available' => 'Ðта Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð½ÐµÐ´Ð¾Ñтупна, еÑли вы иÑпользуете Firefly III в Ñреде Sandstorm.io.',
diff --git a/resources/lang/ru_RU/form.php b/resources/lang/ru_RU/form.php
index 5c9646a382..a4b4ef54cf 100644
--- a/resources/lang/ru_RU/form.php
+++ b/resources/lang/ru_RU/form.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
// new user:
'bank_name' => 'Ðазвание банка',
@@ -184,6 +185,13 @@ return [
'blocked' => 'Заблокирован?',
'blocked_code' => 'Причина блокировки',
+ // import
+ 'apply_rules' => 'Применить правила',
+ 'artist' => 'ИÑполнитель',
+ 'album' => 'Ðльбом',
+ 'song' => 'КомпозициÑ',
+
+
// admin
'domain' => 'Домен',
'single_user_mode' => 'Отключить региÑтрацию пользователей',
diff --git a/resources/lang/ru_RU/import.php b/resources/lang/ru_RU/import.php
index bf6e0fe5ca..457e18aed2 100644
--- a/resources/lang/ru_RU/import.php
+++ b/resources/lang/ru_RU/import.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
- // status of import:
+ // ALL breadcrumbs and subtitles:
+ 'index_breadcrumb' => 'Импорт данных в Firefly III',
+ 'prerequisites_breadcrumb_fake' => 'Prerequisites for the fake import provider',
+ 'prerequisites_breadcrumb_spectre' => 'Prerequisites for Spectre',
+ 'prerequisites_breadcrumb_bunq' => 'Prerequisites for bunq',
+ 'job_configuration_breadcrumb' => 'ÐšÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ Ð´Ð»Ñ ":key"',
+ 'job_status_breadcrumb' => 'Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Ð¸Ð¼Ð¿Ð¾Ñ€Ñ‚Ð° Ð´Ð»Ñ ":key"',
+ 'cannot_create_for_provider' => 'Firefly III не может Ñоздать задачу Ð´Ð»Ñ ":provider"-провайдера.',
+
+ // index page:
+ 'general_index_title' => 'Импортировать файл',
+ 'general_index_intro' => 'Добро пожаловать в инÑтрумент импорта Firefly III. СущеÑтвует неÑколько ÑпоÑобов импорта данных в Firefly III, отображаемых здеÑÑŒ в виде кнопок.',
+ // import provider strings (index):
+ 'button_fake' => 'Поддельный (демо) импорт',
+ 'button_file' => 'Импортировать файл',
+ 'button_bunq' => 'Импорт из bunq',
+ 'button_spectre' => 'Импорт Ñ Ð¸Ñпользованием Spectre',
+ 'button_plaid' => 'Импорт Ñ Ð¸Ñпользованием Plaid',
+ 'button_yodlee' => 'Импорт Ñ Ð¸Ñпользованием Yodlee',
+ 'button_quovo' => 'Импорт Ñ Ð¸Ñпользованием Quovo',
+ // global config box (index)
+ 'global_config_title' => 'Глобальные наÑтройки импорта',
+ 'global_config_text' => 'In the future, this box will feature preferences that apply to ALL import providers above.',
+ // prerequisites box (index)
+ 'need_prereq_title' => 'Import prerequisites',
+ 'need_prereq_intro' => 'Some import methods need your attention before they can be used. For example, they might require special API keys or application secrets. You can configure them here. The icon indicates if these prerequisites have been met.',
+ 'do_prereq_fake' => 'Prerequisites for the fake provider',
+ 'do_prereq_file' => 'Prerequisites for file imports',
+ 'do_prereq_bunq' => 'Prerequisites for imports from bunq',
+ 'do_prereq_spectre' => 'Prerequisites for imports using Spectre',
+ 'do_prereq_plaid' => 'Prerequisites for imports using Plaid',
+ 'do_prereq_yodlee' => 'Prerequisites for imports using Yodlee',
+ 'do_prereq_quovo' => 'Prerequisites for imports using Quovo',
+ // provider config box (index)
+ 'can_config_title' => 'Импорт конфигурации',
+ 'can_config_intro' => 'Some import methods can be configured to your liking. They have extra settings you can tweak.',
+ 'do_config_fake' => 'Configuration for the fake provider',
+ 'do_config_file' => 'Configuration for file imports',
+ 'do_config_bunq' => 'Configuration for bunq imports',
+ 'do_config_spectre' => 'ÐšÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ Ð´Ð»Ñ Ð¸Ð¼Ð¿Ð¾Ñ€Ñ‚Ð° из Spectre',
+ 'do_config_plaid' => 'ÐšÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ Ð´Ð»Ñ Ð¸Ð¼Ð¿Ð¾Ñ€Ñ‚Ð° из Plaid',
+ 'do_config_yodlee' => 'ÐšÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ Ð´Ð»Ñ Ð¸Ð¼Ð¿Ð¾Ñ€Ñ‚Ð° из Yodlee',
+ 'do_config_quovo' => 'ÐšÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ Ð´Ð»Ñ Ð¸Ð¼Ð¿Ð¾Ñ€Ñ‚Ð° из Quovo',
+
+ // prerequisites:
+ 'prereq_fake_title' => 'Prerequisites for an import from the fake import provider',
+ 'prereq_fake_text' => 'This fake provider requires a fake API key. It must be 32 characters long. You can use this one: 123456789012345678901234567890AA',
+ 'prereq_spectre_title' => 'Prerequisites for an import using the Spectre API',
+ 'prereq_spectre_text' => 'In order to import data using the Spectre API (v4), you must provide Firefly III with two secret values. They can be found on the secrets page.',
+ 'prereq_spectre_pub' => 'Likewise, the Spectre API needs to know the public key you see below. Without it, it will not recognize you. Please enter this public key on your secrets page.',
+ 'prereq_bunq_title' => 'Prerequisites for an import from bunq',
+ 'prereq_bunq_text' => 'In order to import from bunq, you need to obtain an API key. You can do this through the app. Please note that the import function for bunq is in BETA. It has only been tested against the sandbox API.',
+ 'prereq_bunq_ip' => 'bunq requires your externally facing IP address. Firefly III has tried to fill this in using the ipify service. Make sure this IP address is correct, or the import will fail.',
+ // prerequisites success messages:
+ 'prerequisites_saved_for_fake' => 'Ключ Fake API уÑпешно Ñохранен!',
+ 'prerequisites_saved_for_spectre' => 'App ID and secret stored!',
+ 'prerequisites_saved_for_bunq' => 'API key and IP stored!',
+
+ // job configuration:
+ 'job_config_apply_rules_title' => 'Job configuration - apply your rules?',
+ 'job_config_apply_rules_text' => 'Once the fake provider has run, your rules can be applied to the transactions. This adds time to the import.',
+ 'job_config_input' => 'Your input',
+ // job configuration for the fake provider:
+ 'job_config_fake_artist_title' => 'Enter album name',
+ 'job_config_fake_artist_text' => 'Many import routines have a few configuration steps you must go through. In the case of the fake import provider, you must answer some weird questions. In this case, enter "David Bowie" to continue.',
+ 'job_config_fake_song_title' => 'Enter song name',
+ 'job_config_fake_song_text' => 'Mention the song "Golden years" to continue with the fake import.',
+ 'job_config_fake_album_title' => 'Enter album name',
+ 'job_config_fake_album_text' => 'Some import routines require extra data halfway through the import. In the case of the fake import provider, you must answer some weird questions. Enter "Station to station" to continue.',
+ // job configuration form the file provider
+ 'job_config_file_upload_title' => 'Import setup (1/4) - Upload your file',
+ 'job_config_file_upload_text' => 'This routine will help you import files from your bank into Firefly III. ',
+ 'job_config_file_upload_help' => 'Select your file. Please make sure the file is UTF-8 encoded.',
+ 'job_config_file_upload_config_help' => 'If you have previously imported data into Firefly III, you may have a configuration file, which will pre-set configuration values for you. For some banks, other users have kindly provided their configuration file',
+ 'job_config_file_upload_type_help' => 'Select the type of file you will upload',
+ 'job_config_file_upload_submit' => 'Загрузить файлы',
+ 'import_file_type_csv' => 'CSV (значениÑ, разделенные запÑтыми)',
+ 'file_not_utf8' => 'The file you have uploaded is not encoded as UTF-8 or ASCII. Firefly III cannot handle such files. Please use Notepad++ or Sublime to convert your file to UTF-8.',
+ 'job_config_uc_title' => 'Import setup (2/4) - Basic file setup',
+ 'job_config_uc_text' => 'To be able to import your file correctly, please validate the options below.',
+ 'job_config_uc_header_help' => 'Check this box if the first row of your CSV file are the column titles.',
+ 'job_config_uc_date_help' => 'Date time format in your file. Follow the format as this page indicates. The default value will parse dates that look like this: :dateExample.',
+ 'job_config_uc_delimiter_help' => 'Choose the field delimiter that is used in your input file. If not sure, comma is the safest option.',
+ 'job_config_uc_account_help' => 'If your file does NOT contain information about your asset account(s), use this dropdown to select to which account the transactions in the file belong to.',
+ 'job_config_uc_apply_rules_title' => 'Apply rules',
+ 'job_config_uc_apply_rules_text' => 'Applies your rules to every imported transaction. Note that this slows the import significantly.',
+ 'job_config_uc_specifics_title' => 'Bank-specific options',
+ 'job_config_uc_specifics_txt' => 'Some banks deliver badly formatted files. Firefly III can fix those automatically. If your bank delivers such files but it\'s not listed here, please open an issue on GitHub.',
+ 'job_config_uc_submit' => 'Продолжить',
+ 'invalid_import_account' => 'You have selected an invalid account to import into.',
+ // job configuration for Spectre:
+ 'job_config_spectre_login_title' => 'Choose your login',
+ 'job_config_spectre_login_text' => 'Firefly III has found :count existing login(s) in your Spectre account. Which one would you like to use to import from?',
+ 'spectre_login_status_active' => 'Active',
+ 'spectre_login_status_inactive' => 'Inactive',
+ 'spectre_login_status_disabled' => 'Disabled',
+ 'spectre_login_new_login' => 'Login with another bank, or one of these banks with different credentials.',
+ 'job_config_spectre_accounts_title' => 'Select accounts to import from',
+ 'job_config_spectre_accounts_text' => 'You have selected ":name" (:country). You have :count account(s) available from this provider. Please select the Firefly III asset account(s) where the transactions from these accounts should be stored. Remember, in order to import data both the Firefly III account and the ":name"-account must have the same currency.',
+ 'spectre_no_supported_accounts' => 'You cannot import from this account due to a currency mismatch.',
+ 'spectre_do_not_import' => '(do not import)',
+ 'spectre_no_mapping' => 'It seems you have not selected any accounts to import from.',
+ 'imported_from_account' => 'Imported from ":account"',
+ 'spectre_account_with_number' => 'Account :number',
+ // job configuration for bunq:
+ 'job_config_bunq_accounts_title' => 'bunq accounts',
+ 'job_config_bunq_accounts_text' => 'These are the accounts associated with your bunq account. Please select the accounts from which you want to import, and in which account the transactions must be imported.',
+ 'bunq_no_mapping' => 'It seems you have not selected any accounts.',
+ 'should_download_config' => 'You should download the configuration file for this job. This will make future imports way easier.',
+ 'share_config_file' => 'If you have imported data from a public bank, you should share your configuration file so it will be easy for other users to import their data. Sharing your configuration file will not expose your financial details.',
+
+ // keys from "extra" array:
+ 'spectre_extra_key_iban' => 'IBAN',
+ 'spectre_extra_key_swift' => 'SWIFT',
+ 'spectre_extra_key_status' => 'Status',
+ 'spectre_extra_key_card_type' => 'Card type',
+ 'spectre_extra_key_account_name' => 'Account name',
+ 'spectre_extra_key_client_name' => 'Client name',
+ 'spectre_extra_key_account_number' => 'Account number',
+ 'spectre_extra_key_blocked_amount' => 'Blocked amount',
+ 'spectre_extra_key_available_amount' => 'Available amount',
+ 'spectre_extra_key_credit_limit' => 'Credit limit',
+ 'spectre_extra_key_interest_rate' => 'Interest rate',
+ 'spectre_extra_key_expiry_date' => 'Expiry date',
+ 'spectre_extra_key_open_date' => 'Open date',
+ 'spectre_extra_key_current_time' => 'Current time',
+ 'spectre_extra_key_current_date' => 'Current date',
+ 'spectre_extra_key_cards' => 'Cards',
+ 'spectre_extra_key_units' => 'Units',
+ 'spectre_extra_key_unit_price' => 'Unit price',
+ 'spectre_extra_key_transactions_count' => 'Transaction count',
+
+ // specifics:
+ 'specific_ing_name' => 'ING NL',
+ 'specific_ing_descr' => 'Create better descriptions in ING exports',
+ 'specific_sns_name' => 'SNS / Volksbank NL',
+ 'specific_sns_descr' => 'Trim quotes from SNS / Volksbank export files',
+ 'specific_abn_name' => 'ABN AMRO NL',
+ 'specific_abn_descr' => 'Fixes potential problems with ABN AMRO files',
+ 'specific_rabo_name' => 'Rabobank NL',
+ 'specific_rabo_descr' => 'Fixes potential problems with Rabobank files',
+ 'specific_pres_name' => 'President\'s Choice Financial CA',
+ 'specific_pres_descr' => 'Fixes potential problems with PC files',
+ // job configuration for file provider (stage: roles)
+ 'job_config_roles_title' => 'Import setup (3/4) - Define each column\'s role',
+ 'job_config_roles_text' => 'Each column in your CSV file contains certain data. Please indicate what kind of data the importer should expect. The option to "map" data means that you will link each entry found in the column to a value in your database. An often mapped column is the column that contains the IBAN of the opposing account. That can be easily matched to IBAN\'s present in your database already.',
+ 'job_config_roles_submit' => 'Continue',
+ 'job_config_roles_column_name' => 'Name of column',
+ 'job_config_roles_column_example' => 'Column example data',
+ 'job_config_roles_column_role' => 'Column data meaning',
+ 'job_config_roles_do_map_value' => 'Map these values',
+ 'job_config_roles_no_example' => 'No example data available',
+ 'job_config_roles_fa_warning' => 'If you mark a column as containing an amount in a foreign currency, you must also set the column that contains which currency it is.',
+ 'job_config_roles_rwarning' => 'At the very least, mark one column as the amount-column. It is advisable to also select a column for the description, date and the opposing account.',
+ 'job_config_roles_colum_count' => 'Column',
+ // job config for the file provider (stage: mapping):
+ 'job_config_map_title' => 'Import setup (4/4) - Connect import data to Firefly III data',
+ 'job_config_map_text' => 'In the following tables, the left value shows you information found in your uploaded file. It is your task to map this value, if possible, to a value already present in your database. Firefly will stick to this mapping. If there is no value to map to, or you do not wish to map the specific value, select nothing.',
+ 'job_config_map_nothing' => 'There is no data present in your file that you can map to existing values. Please press "Start the import" to continue.',
+ 'job_config_field_value' => 'Field value',
+ 'job_config_field_mapped' => 'Mapped to',
+ 'map_do_not_map' => '(не ÑопоÑтавлено)',
+ 'job_config_map_submit' => 'Start the import',
+
+
+ // import status page:
+ 'import_with_key' => 'Импорт Ñ ÐºÐ»ÑŽÑ‡ÐµÐ¼ \':key\'',
'status_wait_title' => 'ПожалуйÑта, подождите...',
'status_wait_text' => 'Ðто Ñообщение иÑчезнет через мгновение.',
- 'status_fatal_title' => 'Произошла критичеÑÐºÐ°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ°',
- 'status_fatal_text' => 'Произошла Ñ„Ð°Ñ‚Ð°Ð»ÑŒÐ½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ°, из-за которой невозможно воÑÑтановить процедуру импорта. ПожалуйÑта, ознакомьтеÑÑŒ Ñ Ð¿Ð¾ÑÑнением в краÑном блоке ниже.',
- 'status_fatal_more' => 'ЕÑли ошибка вызывает тайм-аут, импорт оÑтановитÑÑ Ð½Ð° полпути. Ð”Ð»Ñ Ð½ÐµÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ñ… конфигураций Ñерверов Ñто означает, что Ñервер оÑтановилÑÑ, Ñ…Ð¾Ñ‚Ñ Ð¸Ð¼Ð¿Ð¾Ñ€Ñ‚ продолжает работать в фоновом режиме. Чтобы проверить, так ли Ñто, проверьте лог-файл. ЕÑли проблема не уÑтранена, попробуйте запуÑтить импорт из командной Ñтроки.',
- 'status_ready_title' => 'Импорт готов к запуÑку',
- 'status_ready_text' => 'Импорт готов к запуÑку. Ð’Ñе необходимые наÑтройки были Ñделаны. ПожалуйÑта, загрузите файл конфигурации. Ðто поможет повторно запуÑтить импорт, еÑли что-то пойдет не так, как планировалоÑÑŒ. Чтобы непоÑредÑтвенно запуÑтить импорт, вы можете либо выполнить Ñледующую команду в конÑоли, либо запуÑтить веб-импорт. Ð’ завиÑимоÑти от вашей конфигурации импорт Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ конÑоли может быть более информативен.',
- 'status_ready_noconfig_text' => 'Импорт готов к запуÑку. Ð’Ñе необходимые наÑтройки были Ñделаны. Чтобы непоÑредÑтвенно запуÑтить импорт, вы можете либо выполнить Ñледующую команду в конÑоли, либо запуÑтить веб-импорт. Ð’ завиÑимоÑти от вашей конфигурации импорт Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ конÑоли может быть более информативен.',
- 'status_ready_config' => 'Загрузить конфигурацию',
- 'status_ready_start' => 'Ðачать импорт',
- 'status_ready_share' => 'ПожалуйÑта, раÑÑмотрите возможноÑть загрузки вашей конфигурации в центр импорта конфигураций. Ðто позволит другим пользователÑм Firefly III проще импортировать Ñвои файлы.',
- 'status_job_new' => 'ÐÐ¾Ð²Ð°Ñ Ð·Ð°Ð´Ð°Ñ‡Ð°.',
- 'status_job_configuring' => 'Импорт наÑтроен.',
- 'status_job_configured' => 'Импорт наÑтроен.',
- 'status_job_running' => 'Импорт запущен. ПожалуйÑта, подождите...',
- 'status_job_error' => 'Ðто задание вызвало ошибку.',
- 'status_job_finished' => 'Импорт завершен!',
'status_running_title' => 'ВыполнÑетÑÑ Ð¸Ð¼Ð¿Ð¾Ñ€Ñ‚',
- 'status_running_placeholder' => 'ПожалуйÑта, дождитеÑÑŒ, пока Ñтраница обновитÑÑ...',
- 'status_finished_title' => 'Процедура импорта завершена',
- 'status_finished_text' => 'Ваши данные были импортированы.',
- 'status_errors_title' => 'Ошибки во Ð²Ñ€ÐµÐ¼Ñ Ð¸Ð¼Ð¿Ð¾Ñ€Ñ‚Ð°',
- 'status_errors_single' => 'Во Ð²Ñ€ÐµÐ¼Ñ Ð¸Ð¼Ð¿Ð¾Ñ€Ñ‚Ð° произошла ошибка. Однако, она не привела к фатальным поÑледÑтвиÑм.',
- 'status_errors_multi' => 'Во Ð²Ñ€ÐµÐ¼Ñ Ð¸Ð¼Ð¿Ð¾Ñ€Ñ‚Ð° произошли ошибки. Однако, они не привели к фатальным поÑледÑтвиÑм.',
- 'status_bread_crumb' => 'Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Ð¸Ð¼Ð¿Ð¾Ñ€Ñ‚Ð°',
- 'status_sub_title' => 'Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Ð¸Ð¼Ð¿Ð¾Ñ€Ñ‚Ð°',
- 'config_sub_title' => 'ÐаÑтройте Ñвой импорт',
- 'status_finished_job' => 'Ð’Ñего :count транзакций было импортировано. Они могу быть найдены по метке :tag.',
- 'status_finished_no_tag' => 'Firefly III не Ñобрал никаких транзакций из вашего файла импорта.',
- 'import_with_key' => 'Импорт Ñ ÐºÐ»ÑŽÑ‡ÐµÐ¼ \':key\'',
+ 'status_job_running' => 'Please wait, running the import...',
+ 'status_job_storing' => 'Please wait, storing data...',
+ 'status_job_rules' => 'Please wait, running rules...',
+ 'status_fatal_title' => 'Fatal error',
+ 'status_fatal_text' => 'The import has suffered from an error it could not recover from. Apologies!',
+ 'status_fatal_more' => 'This (possibly very cryptic) error message is complemented by log files, which you can find on your hard drive, or in the Docker container where you run Firefly III from.',
+ 'status_finished_title' => 'Import finished',
+ 'status_finished_text' => 'The import has finished.',
+ 'finished_with_errors' => 'There were some errors during the import. Please review them carefully.',
+ 'unknown_import_result' => 'Unknown import result',
+ 'result_no_transactions' => 'No transactions have been imported. Perhaps they were all duplicates is simply no transactions where present to be imported. Perhaps the log files can tell you what happened. If you import data regularly, this is normal.',
+ 'result_one_transaction' => 'Exactly one transaction has been imported. It is stored under tag :tag where you can inspect it further.',
+ 'result_many_transactions' => 'Firefly III has imported :count transactions. They are stored under tag :tag where you can inspect them further.',
- // file, upload something
- 'file_upload_title' => 'ÐаÑтройка импорта (1/4) - Загрузите ваш файл',
- 'file_upload_text' => 'Ðта процедура поможет вам импортировать файлы из вашего банка в Firefly III. ПожалуйÑта, прочитайте Ñправку, доÑтупную в правом верхнем углу Ñтой Ñтраницы.',
- 'file_upload_fields' => 'ПолÑ',
- 'file_upload_help' => 'Выберите файл',
- 'file_upload_config_help' => 'ЕÑли вы ранее импортировали данные в Firefly III, у Ð²Ð°Ñ Ð¼Ð¾Ð¶ÐµÑ‚ быть файл конфигурации, который позволит вам загрузить готовые наÑтойки. Ð”Ð»Ñ Ð½ÐµÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ñ… банков другие пользователи любезно предоÑтавили Ñвои файлы конфигурации',
- 'file_upload_type_help' => 'Выберите тип загружаемого файла',
- 'file_upload_submit' => 'Загрузить файлы',
- // file, upload types
- 'import_file_type_csv' => 'CSV (значениÑ, разделенные запÑтыми)',
+ // general errors and warnings:
+ 'bad_job_status' => 'To access this page, your import job cannot have status ":status".',
- // file, initial config for CSV
- 'csv_initial_title' => 'ÐаÑтройка импорта (2/4) - ОÑновные наÑтройки CSV-импорта',
- 'csv_initial_text' => 'Чтобы импорт данных прошёл уÑпешно, пожалуйÑта проверьте неÑколько параметров.',
- 'csv_initial_box' => 'ОÑновные параметры импорта CSV',
- 'csv_initial_box_title' => 'ОÑновные параметры импорта CSV',
- 'csv_initial_header_help' => 'УÑтановите Ñтот флажок, еÑли Ð¿ÐµÑ€Ð²Ð°Ñ Ñтрока CSV-файла Ñодержит заголовки Ñтолбцов.',
- 'csv_initial_date_help' => 'Формат даты и времени в вашем CSV-файле. ПридерживайтеÑÑŒ формата, опиÑанного на Ñтой Ñтранице. По умолчанию дату будут анализироватьÑÑ Ð½Ð° ÑоответÑтвие такому формату: :dateExample.',
- 'csv_initial_delimiter_help' => 'Выберите разделитель полей, который иÑпользуетÑÑ Ð² вашем файле. ЕÑли вы не уверены, помните, что запÑÑ‚Ð°Ñ - Ñто Ñамый безопаÑный вариант.',
- 'csv_initial_import_account_help' => 'ЕÑли ваш CSV-файл ÐЕ СОДЕРЖИТ информацию о ваших Ñчетах, иÑпользуйте Ñтот выпадающий ÑпиÑок, чтобы выбрать, к какому Ñчёту отноÑÑÑ‚ÑÑ Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ð¸ в CVS-файле.',
- 'csv_initial_submit' => 'Перейти к шагу 3/4',
-
- // file, new options:
- 'file_apply_rules_title' => 'Применить правила',
- 'file_apply_rules_description' => 'Применить ваши правила. Обратите внимание, что Ñто значительно замедлÑет импорт.',
- 'file_match_bills_title' => 'СоответÑтвующие Ñчета к оплате',
- 'file_match_bills_description' => 'СопоÑтавление Ñвои Ñчета к оплате Ñ Ð²Ð½Ð¾Ð²ÑŒ Ñозданными раÑходами. Помните, что Ñто может ÑущеÑтвенно замедлить импорт.',
-
- // file, roles config
- 'csv_roles_title' => 'ÐаÑтройка импорта (3/4). Определите роль каждого Ñтолбца',
- 'csv_roles_text' => 'Каждый Ñтолбец в файле CSV Ñодержит определённые данные. Укажите, какие данные должен ожидать импортер. ÐžÐ¿Ñ†Ð¸Ñ Â«ÑопоÑтавить» данные привÑжет каждую запиÑÑŒ, найденную в Ñтолбце, к значению в вашей базе данных. ЧаÑто отображаемый Ñтолбец - Ñто Ñтолбец, Ñодержащий IBAN ÑпонÑорÑкого Ñчёта. Его можно легко ÑопоÑтавить Ñ ÑущеÑтвующим в вашей базе данных IBAN.',
- 'csv_roles_table' => 'Таблица',
- 'csv_roles_column_name' => 'Ðазвание Ñтолбца',
- 'csv_roles_column_example' => 'Пример данных в Ñтолбце',
- 'csv_roles_column_role' => 'Значение в Ñтолбце',
- 'csv_roles_do_map_value' => 'СопоÑтавьте Ñти значениÑ',
- 'csv_roles_column' => 'Столбец',
- 'csv_roles_no_example_data' => 'Ðет доÑтупных данных Ð´Ð»Ñ Ð¿Ñ€Ð¸Ð¼ÐµÑ€Ð°',
- 'csv_roles_submit' => 'Перейти к шагу 4/4',
-
- // not csv, but normal warning
- 'roles_warning' => 'ПожалуйÑта, отметьте Ñ…Ð¾Ñ‚Ñ Ð±Ñ‹ один Ñтолбец как Ñтолбец Ñ Ñуммой. Также целеÑообразно выбрать Ñтолбец Ð´Ð»Ñ Ð¾Ð¿Ð¸ÑаниÑ, даты и ÑпонÑорÑкого Ñчёта.',
- 'foreign_amount_warning' => 'ЕÑли вы пометите Ñтот Ñтолбец, как Ñодержащий Ñумму в иноÑтранной валюте, вы также должны указать Ñтолбец, который указывает, ÐºÐ°ÐºÐ°Ñ Ð¸Ð¼ÐµÐ½Ð½Ð¾ Ñто валюта.',
-
- // file, map data
- 'file_map_title' => 'ÐаÑтройки импорта (4/4) - СопоÑтавление данных импорта Ñ Ð´Ð°Ð½Ð½Ñ‹Ð¼Ð¸ Firefly III',
- 'file_map_text' => 'Ð’ Ñледующих таблицах значение Ñлева отображает информацию, найденную в загруженном файле. Ваша задача - ÑопоÑтавить Ñто значение (еÑли Ñто возможно) Ñо значением, уже имеющимÑÑ Ð² вашей базе данных. Firefly будет придерживатьÑÑ Ñтого ÑопоÑтавлениÑ. ЕÑли Ð´Ð»Ñ ÑопоÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð½ÐµÑ‚ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð¸Ð»Ð¸ вы не хотите отображать определённое значение, ничего не выбирайте.',
- 'file_map_field_value' => 'Значение полÑ',
- 'file_map_field_mapped_to' => 'СопоÑтавлено Ñ',
- 'map_do_not_map' => '(не ÑопоÑтавлено)',
- 'file_map_submit' => 'Ðачать импорт',
- 'file_nothing_to_map' => 'Ð’ вашем файле нет данных, которые можно ÑопоÑтавить Ñ ÑущеÑтвующими значениÑми. Ðажмите «Ðачать импорт», чтобы продолжить.',
-
- // map things.
+ // column roles for CSV import:
'column__ignore' => '(игнорировать Ñтот Ñтолбец)',
'column_account-iban' => 'Счет актива (IBAN)',
'column_account-id' => 'ID оÑновного Ñчёта (ÑоответÑтвующий FF3)',
@@ -158,48 +261,4 @@ return [
'column_note' => 'ПримечаниÑ',
'column_internal-reference' => 'ВнутреннÑÑ ÑÑылка',
- // prerequisites
- 'prerequisites' => 'ТребованиÑ',
-
- // bunq
- 'bunq_prerequisites_title' => 'Ð¢Ñ€ÐµÐ±Ð¾Ð²Ð°Ð½Ð¸Ñ Ð´Ð»Ñ Ð¸Ð¼Ð¿Ð¾Ñ€Ñ‚Ð° из bunq',
- 'bunq_prerequisites_text' => 'Чтобы импортировать из bunq, вам нужно получить ключ API. Ð’Ñ‹ можете Ñделать Ñто через приложение. Обратите внимание, что Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð¸Ð¼Ð¿Ð¾Ñ€Ñ‚Ð° Ð´Ð»Ñ bunq находитÑÑ Ð² бета-теÑтированиÑ. Было протеÑтировано только API пеÑочницы (sandbox).',
- 'bunq_prerequisites_text_ip' => 'Ð”Ð»Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ñ‹ Ñ Bunq необходимо указать ваш внешний IP-адреÑ. Firefly III попыталÑÑ ÑƒÐ·Ð½Ð°Ñ‚ÑŒ ваш Ð°Ð´Ñ€ÐµÑ Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ Ñлужбы ipify. УбедитеÑÑŒ, что Ñтот IP-Ð°Ð´Ñ€ÐµÑ Ð²ÐµÑ€ÐµÐ½, иначе импорт не будет выполнен.',
- 'bunq_do_import' => 'Да, импортировать Ñ Ñтого Ñчёта',
- 'bunq_accounts_title' => 'Счета Bunq',
- 'bunq_accounts_text' => 'Ðти Ñчета ÑвÑзаны Ñ Ð²Ð°ÑˆÐµÐ¹ учётной запиÑью bunq. Выберите Ñчета, данные о о которых вы хотите импортировать, и Ñчёт, на который будут импортированы транзакции.',
-
- // Spectre
- 'spectre_title' => 'Импорт Ñ Ð¸Ñпользованием Spectre',
- 'spectre_prerequisites_title' => 'Ð¢Ñ€ÐµÐ±Ð¾Ð²Ð°Ð½Ð¸Ñ Ð´Ð»Ñ Ð¸Ð¼Ð¿Ð¾Ñ€Ñ‚Ð° Ñ Ð¸Ñпользованием Spectre',
- 'spectre_prerequisites_text' => 'Чтобы импортировать данные Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ Spectre API (v4), вы должны предоÑтавить Firefly III два Ñекретных значениÑ. Их можно найти на Ñтранице secrets page.',
- 'spectre_enter_pub_key' => 'Импорт будет работать только еÑли вы введёте Ñтот ключ безопаÑноÑти на Ñтранице Ñ ÐºÐ»ÑŽÑ‡Ð°Ð¼Ð¸ в Ñвоём аккаунте.',
- 'spectre_accounts_title' => 'Выберите Ñчёта, Ñ ÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ñ… будет производитьÑÑ Ð¸Ð¼Ð¿Ð¾Ñ€Ñ‚',
- 'spectre_accounts_text' => 'Каждый Ñчёт в ÑпиÑке Ñлева был найден в в Spectre и может быть импортирован в Firefly III. Выберите оÑновной Ñчёт, на котором нужно Ñохранить импортируемые транзакции. ЕÑли вы не хотите импортировать данные Ñ ÐºÐ°ÐºÐ¾Ð³Ð¾-либо конкретного Ñчёта, Ñнимите ÑоответÑтвующий флажок.',
- 'spectre_do_import' => 'Да, импортировать Ñ Ñтого Ñчёта',
- 'spectre_no_supported_accounts' => 'Ð’Ñ‹ не можете импортировать Ñ Ñтого Ñчёта из-за неÑоответÑÑ‚Ð²Ð¸Ñ Ð²Ð°Ð»ÑŽÑ‚Ñ‹.',
-
- // keys from "extra" array:
- 'spectre_extra_key_iban' => 'IBAN',
- 'spectre_extra_key_swift' => 'SWIFT',
- 'spectre_extra_key_status' => 'СтатуÑ',
- 'spectre_extra_key_card_type' => 'Тип карты',
- 'spectre_extra_key_account_name' => 'Ðазвание Ñчёта',
- 'spectre_extra_key_client_name' => 'Ð˜Ð¼Ñ ÐºÐ»Ð¸ÐµÐ½Ñ‚Ð°',
- 'spectre_extra_key_account_number' => 'Ðомер Ñчёта',
- 'spectre_extra_key_blocked_amount' => 'Ð—Ð°Ð±Ð»Ð¾ÐºÐ¸Ñ€Ð¾Ð²Ð°Ð½Ð½Ð°Ñ Ñумма',
- 'spectre_extra_key_available_amount' => 'ДоÑÑ‚ÑƒÐ¿Ð½Ð°Ñ Ñумма',
- 'spectre_extra_key_credit_limit' => 'Кредитный лимит',
- 'spectre_extra_key_interest_rate' => 'ÐŸÑ€Ð¾Ñ†ÐµÐ½Ñ‚Ð½Ð°Ñ Ñтавка',
- 'spectre_extra_key_expiry_date' => 'Дата окончаниÑ',
- 'spectre_extra_key_open_date' => 'Дата открытиÑ',
- 'spectre_extra_key_current_time' => 'Текущее времÑ',
- 'spectre_extra_key_current_date' => 'Ð¢ÐµÐºÑƒÑ‰Ð°Ñ Ð´Ð°Ñ‚Ð°',
- 'spectre_extra_key_cards' => 'Карты',
- 'spectre_extra_key_units' => 'Единицы',
- 'spectre_extra_key_unit_price' => 'Цена за единицу',
- 'spectre_extra_key_transactions_count' => 'КоличеÑтво транзакций',
-
- // various other strings:
- 'imported_from_account' => 'Импортировано Ñо Ñчёта ":account"',
];
diff --git a/resources/lang/ru_RU/intro.php b/resources/lang/ru_RU/intro.php
index 40f7a5dd48..8f21f6457e 100644
--- a/resources/lang/ru_RU/intro.php
+++ b/resources/lang/ru_RU/intro.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
// index
'index_intro' => 'Добро пожаловать на Ñтартовую Ñтраницу Firefly III. ПожалуйÑта, найдите времÑ, чтобы ознакомитьÑÑ Ñ Ñтим кратким введением в возможноÑти Firefly III.',
diff --git a/resources/lang/ru_RU/list.php b/resources/lang/ru_RU/list.php
index effe3f6184..ad3e77cc87 100644
--- a/resources/lang/ru_RU/list.php
+++ b/resources/lang/ru_RU/list.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
'buttons' => 'Кнопки',
'icon' => 'Значок',
@@ -111,10 +112,15 @@ return [
'sepa-cc' => 'Код очиÑтки SEPA',
'sepa-ep' => 'ВнешнÑÑ Ñ†ÐµÐ»ÑŒ SEPA',
'sepa-ci' => 'Идентификатор кредитора SEPA',
+ 'external_id' => 'Внешний ID',
'account_at_bunq' => 'Счёт Ñ bunq',
'file_name' => 'Ð˜Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð°',
'file_size' => 'Размер файла',
'file_type' => 'Тип файла',
'attached_to' => 'Прикреплено к',
'file_exists' => 'Файл ÑущеÑтвует',
+ 'spectre_bank' => 'Bank',
+ 'spectre_last_use' => 'Last login',
+ 'spectre_status' => 'Status',
+ 'bunq_payment_id' => 'bunq payment ID',
];
diff --git a/resources/lang/ru_RU/pagination.php b/resources/lang/ru_RU/pagination.php
index 686f3d513f..55ea0144e6 100644
--- a/resources/lang/ru_RU/pagination.php
+++ b/resources/lang/ru_RU/pagination.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
'previous' => '« Предыдущие',
'next' => 'Следующие »',
diff --git a/resources/lang/ru_RU/passwords.php b/resources/lang/ru_RU/passwords.php
index 331c788036..b54116eda5 100644
--- a/resources/lang/ru_RU/passwords.php
+++ b/resources/lang/ru_RU/passwords.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
'password' => 'Пароль должен Ñодержать не менее 6 Ñимволов. Пароль и его подтверждение должны Ñовпадать.',
'user' => 'Мы не можем найти Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ñ Ñ‚Ð°ÐºÐ¸Ð¼ e-mail.',
diff --git a/resources/lang/ru_RU/validation.php b/resources/lang/ru_RU/validation.php
index 0aa6c7686d..9d551d5344 100644
--- a/resources/lang/ru_RU/validation.php
+++ b/resources/lang/ru_RU/validation.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
'iban' => 'Ðто некорректный IBAN.',
'source_equals_destination' => 'Счёт иÑточник и Ñчёт Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ñовпадают',
@@ -109,7 +110,8 @@ return [
'in_array' => 'Поле :attribute не ÑущеÑтвует в :other.',
'present' => 'Поле :attribute должно быть заполнено.',
'amount_zero' => 'Общее количеÑтво не может быть равно нулю',
- 'secure_password' => 'Ðто не безопаÑный пароль. Попробуйте еще раз. Ð”Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ñправки поÑетите https://goo.gl/NCh2tN',
+ 'unique_piggy_bank_for_user' => 'The name of the piggy bank must be unique.',
+ 'secure_password' => 'This is not a secure password. Please try again. For more information, visit http://bit.ly/FF3-password-security',
'attributes' => [
'email' => '"ÐÐ´Ñ€ÐµÑ Ñлектронной почты"',
'description' => '"ОпиÑание"',
diff --git a/resources/lang/tr_TR/auth.php b/resources/lang/tr_TR/auth.php
index e51cdeef23..a000fd4e5f 100644
--- a/resources/lang/tr_TR/auth.php
+++ b/resources/lang/tr_TR/auth.php
@@ -1,9 +1,8 @@
.
*/
-return [
- /*
- |--------------------------------------------------------------------------
- | Authentication Language Lines
- |--------------------------------------------------------------------------
- |
- | The following language lines are used during authentication for various
- | messages that we need to display to the user. You are free to modify
- | these language lines according to your application's requirements.
- |
- */
+declare(strict_types=1);
+return [
'failed' => 'Bu kimlik bilgileri kayıtlarımızla uyuşmuyor.',
'throttle' => 'Fazla sayıda oturum açma girişimi. Lütfen :seconds saniye sonra tekrar deneyiniz.',
];
diff --git a/resources/lang/tr_TR/bank.php b/resources/lang/tr_TR/bank.php
index 8826020cbf..5d00b1e685 100644
--- a/resources/lang/tr_TR/bank.php
+++ b/resources/lang/tr_TR/bank.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
];
diff --git a/resources/lang/tr_TR/breadcrumbs.php b/resources/lang/tr_TR/breadcrumbs.php
index 17bc230d6a..82d66d4c65 100644
--- a/resources/lang/tr_TR/breadcrumbs.php
+++ b/resources/lang/tr_TR/breadcrumbs.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
'home' => 'Anasayfa',
'edit_currency' => '":name" para birimini düzenle',
diff --git a/resources/lang/tr_TR/components.php b/resources/lang/tr_TR/components.php
index 50092e06fd..6299088f8e 100644
--- a/resources/lang/tr_TR/components.php
+++ b/resources/lang/tr_TR/components.php
@@ -1,5 +1,4 @@
.
*/
+declare(strict_types=1);
+
return [
// profile
'personal_access_tokens' => 'Personal access tokens',
diff --git a/resources/lang/tr_TR/config.php b/resources/lang/tr_TR/config.php
index 7c3694a155..4bc8b0175d 100644
--- a/resources/lang/tr_TR/config.php
+++ b/resources/lang/tr_TR/config.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
'html_language' => 'tr',
'locale' => 'tr, Turkish, tr_TR, tr_TR.utf8, tr_TR.S.UTF-8',
diff --git a/resources/lang/tr_TR/csv.php b/resources/lang/tr_TR/csv.php
index 622a49202a..aae109a40a 100644
--- a/resources/lang/tr_TR/csv.php
+++ b/resources/lang/tr_TR/csv.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
];
diff --git a/resources/lang/tr_TR/demo.php b/resources/lang/tr_TR/demo.php
index 5c4ee00a0d..f60723c7a3 100644
--- a/resources/lang/tr_TR/demo.php
+++ b/resources/lang/tr_TR/demo.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
'no_demo_text' => 'Maalesef, bu sayfa için daha fazla demo açıklama metni yok.',
'see_help_icon' => 'Ancak, sağ üst köşedeki simge size daha fazla bilgi verebilir.',
@@ -32,5 +33,5 @@ return [
'currencies-index' => 'Firefly III, birden fazla para birimini destekliyor. Euro varsayılan olmasına rağmen, ABD Doları ve diğer birçok para birimine ayarlanabilir. Gördüğünüz gibi küçük bir para birimi seçeneği dedahil edilmiştir ancak isterseniz kendi para biriminizi ekleyebilirsiniz. Varsayılan para birimi değiştirilebilir ancak mevcut işlemlerin para birimi değiştirilemez: Firefly III, aynı anda birden çok para biriminin kullanılmasını destekler.',
'transactions-index' => 'Bu masraflar, mevduatlar ve transferler için özellikle yaratıcı değildir. Bunlar otomatik olarak oluşturuldu.',
'piggy-banks-index' => 'Gördüğünüz gibi, üç tane banka var. Her domuzcuk bankasındaki para miktarını değiştirmek için artı ve eksi düğmelerini kullanın. Her domuzcuk bankasının yönetimini görmek için domuzcuk\'un üzerine tıklayın.',
- 'import-index' => 'Elbette, herhangi bir CVS dosyası Firefly III\'e aktarılabilir',
+ 'import-index' => 'Any CSV file can be imported into Firefly III. It also supports importing data from bunq and Spectre. Other banks and financial aggregators will be implemented in the future. As a demo-user however, you can only see the "fake"-provider in action. It will generate some random transactions to show you how the process works.',
];
diff --git a/resources/lang/tr_TR/firefly.php b/resources/lang/tr_TR/firefly.php
index 43138bb0b3..32747c7c17 100644
--- a/resources/lang/tr_TR/firefly.php
+++ b/resources/lang/tr_TR/firefly.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
// general stuff:
'close' => 'Kapat',
@@ -179,6 +180,7 @@ return [
'authorization_request_intro' => ':client is requesting permission to access your financial administration. Would you like to authorize :client to access these records?',
'scopes_will_be_able' => 'This application will be able to:',
'button_authorize' => 'Authorize',
+ 'none_in_select_list' => '(none)',
// check for updates:
'update_check_title' => 'Check for updates',
@@ -667,6 +669,7 @@ işlemlerin kontrol edildiğini lütfen unutmayın.',
'bill_will_automatch' => 'Fatura uygun işlemlere otomatik olarak bağlandı',
'skips_over' => 'atla',
'bill_store_error' => 'An unexpected error occurred while storing your new bill. Please check the log files',
+ 'list_inactive_rule' => 'inactive rule',
// accounts:
'details_for_asset' => '":name" Varlık hesabı ayrıntıları',
@@ -802,6 +805,7 @@ işlemlerin kontrol edildiğini lütfen unutmayın.',
'opt_group_savingAsset' => 'Tasarruf Hesapları',
'opt_group_sharedAsset' => 'Paylaşılan varlık hesapları',
'opt_group_ccAsset' => 'Kredi Kartı',
+ 'opt_group_cashWalletAsset' => 'Cash wallets',
'notes' => 'Notes',
'unknown_journal_error' => 'Could not store the transaction. Please check the log files.',
@@ -817,6 +821,7 @@ işlemlerin kontrol edildiğini lütfen unutmayın.',
'language' => 'Language',
'new_savings_account' => ':bank_name savings account',
'cash_wallet' => 'Cash wallet',
+ 'currency_not_present' => 'If the currency you normally use is not listed do not worry. You can create your own currencies under Options > Currencies.',
// home page:
'yourAccounts' => 'Hesaplarınız',
@@ -1014,6 +1019,7 @@ işlemlerin kontrol edildiğini lütfen unutmayın.',
'remove_money_from_piggy_title' => '":name" kumbarasından para çek',
'add' => 'Ekle',
'no_money_for_piggy' => 'Bu kumbaraya koyacak paran yok.',
+ 'suggested_savings_per_month' => 'Suggested per month',
'remove' => 'Kaldır',
'max_amount_add' => 'EkleyebileceÄŸiniz azami tutar',
@@ -1149,27 +1155,9 @@ işlemlerin kontrol edildiğini lütfen unutmayın.',
'no_edit_multiple_left' => 'Düzenlemek için geçerli İşlemler seçmediniz.',
'cannot_convert_split_journal' => 'Bölünmüş bir İşlemi dönüştüremezsiniz',
- // import bread crumbs and titles:
- 'import' => 'İçe aktar',
- 'import_data' => 'Veriyi içe aktar',
- 'import_general_index_file' => 'Bir Dosyayı içe aktar',
- 'import_from_bunq' => 'Bunq\'dan aktar',
- 'import_using_spectre' => 'Spectre kullanarak içe aktar',
- 'import_using_plaid' => 'Palid kullanarak içe aktar',
- 'import_config_bread_crumb' => 'Aktarımınızı oluşturunuz',
-
- // import index page:
+ // Import page (general strings only)
'import_index_title' => 'Firefly III\'e veri aktarma',
- 'import_index_sub_title' => 'İndeks',
- 'import_general_index_intro' => 'Welcome to Firefly III\'s import routine. There are a few ways of importing data into Firefly III, displayed here as buttons.',
- 'upload_error' => 'The file you have uploaded could not be processed. Possibly it is of an invalid file type or encoding. The log files will have more information.',
- 'reset_import_settings_title' => 'Reset import configuration',
- 'reset_import_settings_text' => 'You can use these links to reset your import settings for specific providers. This is useful when bad settings stop you from importing data.',
- 'reset_settings_bunq' => 'Remove bunq API key, local external IP address and bunq related RSA keys.',
- 'reset_settings_spectre' => 'Remove Spectre secrets and ID\'s. This will also remove your Spectre keypair. Remember to update the new one.',
- 'settings_reset_for_bunq' => 'Bunq settings reset.',
- 'settings_reset_for_spectre' => 'Spectre settings reset.',
-
+ 'import_data' => 'Veriyi içe aktar',
// sandstorm.io errors and messages:
'sandstorm_not_available' => 'Bir Sandstorm.io ortamında Firefly III kullanıyorsanız, bu işlev kullanılamaz.',
diff --git a/resources/lang/tr_TR/form.php b/resources/lang/tr_TR/form.php
index 0304b33981..ac3f7c5de7 100644
--- a/resources/lang/tr_TR/form.php
+++ b/resources/lang/tr_TR/form.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
// new user:
'bank_name' => 'Banka adı',
@@ -184,6 +185,13 @@ return [
'blocked' => 'Engellendi mi?',
'blocked_code' => 'Blok nedeni',
+ // import
+ 'apply_rules' => 'Apply rules',
+ 'artist' => 'Artist',
+ 'album' => 'Album',
+ 'song' => 'Song',
+
+
// admin
'domain' => 'Alan adı',
'single_user_mode' => 'Kullanıcı kaydını devre dışı bırak',
diff --git a/resources/lang/tr_TR/import.php b/resources/lang/tr_TR/import.php
index 1d7658750c..dd1ecba61d 100644
--- a/resources/lang/tr_TR/import.php
+++ b/resources/lang/tr_TR/import.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
- // status of import:
+ // ALL breadcrumbs and subtitles:
+ 'index_breadcrumb' => 'Import data into Firefly III',
+ 'prerequisites_breadcrumb_fake' => 'Prerequisites for the fake import provider',
+ 'prerequisites_breadcrumb_spectre' => 'Prerequisites for Spectre',
+ 'prerequisites_breadcrumb_bunq' => 'Prerequisites for bunq',
+ 'job_configuration_breadcrumb' => 'Configuration for ":key"',
+ 'job_status_breadcrumb' => 'Import status for ":key"',
+ 'cannot_create_for_provider' => 'Firefly III cannot create a job for the ":provider"-provider.',
+
+ // index page:
+ 'general_index_title' => 'Import a file',
+ 'general_index_intro' => 'Welcome to Firefly III\'s import routine. There are a few ways of importing data into Firefly III, displayed here as buttons.',
+ // import provider strings (index):
+ 'button_fake' => 'Fake an import',
+ 'button_file' => 'Import a file',
+ 'button_bunq' => 'Import from bunq',
+ 'button_spectre' => 'Import using Spectre',
+ 'button_plaid' => 'Import using Plaid',
+ 'button_yodlee' => 'Import using Yodlee',
+ 'button_quovo' => 'Import using Quovo',
+ // global config box (index)
+ 'global_config_title' => 'Global import configuration',
+ 'global_config_text' => 'In the future, this box will feature preferences that apply to ALL import providers above.',
+ // prerequisites box (index)
+ 'need_prereq_title' => 'Import prerequisites',
+ 'need_prereq_intro' => 'Some import methods need your attention before they can be used. For example, they might require special API keys or application secrets. You can configure them here. The icon indicates if these prerequisites have been met.',
+ 'do_prereq_fake' => 'Prerequisites for the fake provider',
+ 'do_prereq_file' => 'Prerequisites for file imports',
+ 'do_prereq_bunq' => 'Prerequisites for imports from bunq',
+ 'do_prereq_spectre' => 'Prerequisites for imports using Spectre',
+ 'do_prereq_plaid' => 'Prerequisites for imports using Plaid',
+ 'do_prereq_yodlee' => 'Prerequisites for imports using Yodlee',
+ 'do_prereq_quovo' => 'Prerequisites for imports using Quovo',
+ // provider config box (index)
+ 'can_config_title' => 'Import configuration',
+ 'can_config_intro' => 'Some import methods can be configured to your liking. They have extra settings you can tweak.',
+ 'do_config_fake' => 'Configuration for the fake provider',
+ 'do_config_file' => 'Configuration for file imports',
+ 'do_config_bunq' => 'Configuration for bunq imports',
+ 'do_config_spectre' => 'Configuration for imports from Spectre',
+ 'do_config_plaid' => 'Configuration for imports from Plaid',
+ 'do_config_yodlee' => 'Configuration for imports from Yodlee',
+ 'do_config_quovo' => 'Configuration for imports from Quovo',
+
+ // prerequisites:
+ 'prereq_fake_title' => 'Prerequisites for an import from the fake import provider',
+ 'prereq_fake_text' => 'This fake provider requires a fake API key. It must be 32 characters long. You can use this one: 123456789012345678901234567890AA',
+ 'prereq_spectre_title' => 'Prerequisites for an import using the Spectre API',
+ 'prereq_spectre_text' => 'In order to import data using the Spectre API (v4), you must provide Firefly III with two secret values. They can be found on the secrets page.',
+ 'prereq_spectre_pub' => 'Likewise, the Spectre API needs to know the public key you see below. Without it, it will not recognize you. Please enter this public key on your secrets page.',
+ 'prereq_bunq_title' => 'Prerequisites for an import from bunq',
+ 'prereq_bunq_text' => 'In order to import from bunq, you need to obtain an API key. You can do this through the app. Please note that the import function for bunq is in BETA. It has only been tested against the sandbox API.',
+ 'prereq_bunq_ip' => 'bunq requires your externally facing IP address. Firefly III has tried to fill this in using the ipify service. Make sure this IP address is correct, or the import will fail.',
+ // prerequisites success messages:
+ 'prerequisites_saved_for_fake' => 'Fake API key stored successfully!',
+ 'prerequisites_saved_for_spectre' => 'App ID and secret stored!',
+ 'prerequisites_saved_for_bunq' => 'API key and IP stored!',
+
+ // job configuration:
+ 'job_config_apply_rules_title' => 'Job configuration - apply your rules?',
+ 'job_config_apply_rules_text' => 'Once the fake provider has run, your rules can be applied to the transactions. This adds time to the import.',
+ 'job_config_input' => 'Your input',
+ // job configuration for the fake provider:
+ 'job_config_fake_artist_title' => 'Enter album name',
+ 'job_config_fake_artist_text' => 'Many import routines have a few configuration steps you must go through. In the case of the fake import provider, you must answer some weird questions. In this case, enter "David Bowie" to continue.',
+ 'job_config_fake_song_title' => 'Enter song name',
+ 'job_config_fake_song_text' => 'Mention the song "Golden years" to continue with the fake import.',
+ 'job_config_fake_album_title' => 'Enter album name',
+ 'job_config_fake_album_text' => 'Some import routines require extra data halfway through the import. In the case of the fake import provider, you must answer some weird questions. Enter "Station to station" to continue.',
+ // job configuration form the file provider
+ 'job_config_file_upload_title' => 'Import setup (1/4) - Upload your file',
+ 'job_config_file_upload_text' => 'This routine will help you import files from your bank into Firefly III. ',
+ 'job_config_file_upload_help' => 'Select your file. Please make sure the file is UTF-8 encoded.',
+ 'job_config_file_upload_config_help' => 'If you have previously imported data into Firefly III, you may have a configuration file, which will pre-set configuration values for you. For some banks, other users have kindly provided their configuration file',
+ 'job_config_file_upload_type_help' => 'Select the type of file you will upload',
+ 'job_config_file_upload_submit' => 'Upload files',
+ 'import_file_type_csv' => 'CSV (virgülle ayrılmış değerler)',
+ 'file_not_utf8' => 'The file you have uploaded is not encoded as UTF-8 or ASCII. Firefly III cannot handle such files. Please use Notepad++ or Sublime to convert your file to UTF-8.',
+ 'job_config_uc_title' => 'Import setup (2/4) - Basic file setup',
+ 'job_config_uc_text' => 'To be able to import your file correctly, please validate the options below.',
+ 'job_config_uc_header_help' => 'Check this box if the first row of your CSV file are the column titles.',
+ 'job_config_uc_date_help' => 'Date time format in your file. Follow the format as this page indicates. The default value will parse dates that look like this: :dateExample.',
+ 'job_config_uc_delimiter_help' => 'Choose the field delimiter that is used in your input file. If not sure, comma is the safest option.',
+ 'job_config_uc_account_help' => 'If your file does NOT contain information about your asset account(s), use this dropdown to select to which account the transactions in the file belong to.',
+ 'job_config_uc_apply_rules_title' => 'Apply rules',
+ 'job_config_uc_apply_rules_text' => 'Applies your rules to every imported transaction. Note that this slows the import significantly.',
+ 'job_config_uc_specifics_title' => 'Bank-specific options',
+ 'job_config_uc_specifics_txt' => 'Some banks deliver badly formatted files. Firefly III can fix those automatically. If your bank delivers such files but it\'s not listed here, please open an issue on GitHub.',
+ 'job_config_uc_submit' => 'Continue',
+ 'invalid_import_account' => 'You have selected an invalid account to import into.',
+ // job configuration for Spectre:
+ 'job_config_spectre_login_title' => 'Choose your login',
+ 'job_config_spectre_login_text' => 'Firefly III has found :count existing login(s) in your Spectre account. Which one would you like to use to import from?',
+ 'spectre_login_status_active' => 'Active',
+ 'spectre_login_status_inactive' => 'Inactive',
+ 'spectre_login_status_disabled' => 'Disabled',
+ 'spectre_login_new_login' => 'Login with another bank, or one of these banks with different credentials.',
+ 'job_config_spectre_accounts_title' => 'Select accounts to import from',
+ 'job_config_spectre_accounts_text' => 'You have selected ":name" (:country). You have :count account(s) available from this provider. Please select the Firefly III asset account(s) where the transactions from these accounts should be stored. Remember, in order to import data both the Firefly III account and the ":name"-account must have the same currency.',
+ 'spectre_no_supported_accounts' => 'You cannot import from this account due to a currency mismatch.',
+ 'spectre_do_not_import' => '(do not import)',
+ 'spectre_no_mapping' => 'It seems you have not selected any accounts to import from.',
+ 'imported_from_account' => 'Imported from ":account"',
+ 'spectre_account_with_number' => 'Account :number',
+ // job configuration for bunq:
+ 'job_config_bunq_accounts_title' => 'bunq accounts',
+ 'job_config_bunq_accounts_text' => 'These are the accounts associated with your bunq account. Please select the accounts from which you want to import, and in which account the transactions must be imported.',
+ 'bunq_no_mapping' => 'It seems you have not selected any accounts.',
+ 'should_download_config' => 'You should download the configuration file for this job. This will make future imports way easier.',
+ 'share_config_file' => 'If you have imported data from a public bank, you should share your configuration file so it will be easy for other users to import their data. Sharing your configuration file will not expose your financial details.',
+
+ // keys from "extra" array:
+ 'spectre_extra_key_iban' => 'IBAN',
+ 'spectre_extra_key_swift' => 'SWIFT',
+ 'spectre_extra_key_status' => 'Status',
+ 'spectre_extra_key_card_type' => 'Card type',
+ 'spectre_extra_key_account_name' => 'Account name',
+ 'spectre_extra_key_client_name' => 'Client name',
+ 'spectre_extra_key_account_number' => 'Account number',
+ 'spectre_extra_key_blocked_amount' => 'Blocked amount',
+ 'spectre_extra_key_available_amount' => 'Available amount',
+ 'spectre_extra_key_credit_limit' => 'Credit limit',
+ 'spectre_extra_key_interest_rate' => 'Interest rate',
+ 'spectre_extra_key_expiry_date' => 'Expiry date',
+ 'spectre_extra_key_open_date' => 'Open date',
+ 'spectre_extra_key_current_time' => 'Current time',
+ 'spectre_extra_key_current_date' => 'Current date',
+ 'spectre_extra_key_cards' => 'Cards',
+ 'spectre_extra_key_units' => 'Units',
+ 'spectre_extra_key_unit_price' => 'Unit price',
+ 'spectre_extra_key_transactions_count' => 'Transaction count',
+
+ // specifics:
+ 'specific_ing_name' => 'ING NL',
+ 'specific_ing_descr' => 'Create better descriptions in ING exports',
+ 'specific_sns_name' => 'SNS / Volksbank NL',
+ 'specific_sns_descr' => 'Trim quotes from SNS / Volksbank export files',
+ 'specific_abn_name' => 'ABN AMRO NL',
+ 'specific_abn_descr' => 'Fixes potential problems with ABN AMRO files',
+ 'specific_rabo_name' => 'Rabobank NL',
+ 'specific_rabo_descr' => 'Fixes potential problems with Rabobank files',
+ 'specific_pres_name' => 'President\'s Choice Financial CA',
+ 'specific_pres_descr' => 'Fixes potential problems with PC files',
+ // job configuration for file provider (stage: roles)
+ 'job_config_roles_title' => 'Import setup (3/4) - Define each column\'s role',
+ 'job_config_roles_text' => 'Each column in your CSV file contains certain data. Please indicate what kind of data the importer should expect. The option to "map" data means that you will link each entry found in the column to a value in your database. An often mapped column is the column that contains the IBAN of the opposing account. That can be easily matched to IBAN\'s present in your database already.',
+ 'job_config_roles_submit' => 'Continue',
+ 'job_config_roles_column_name' => 'Name of column',
+ 'job_config_roles_column_example' => 'Column example data',
+ 'job_config_roles_column_role' => 'Column data meaning',
+ 'job_config_roles_do_map_value' => 'Map these values',
+ 'job_config_roles_no_example' => 'No example data available',
+ 'job_config_roles_fa_warning' => 'If you mark a column as containing an amount in a foreign currency, you must also set the column that contains which currency it is.',
+ 'job_config_roles_rwarning' => 'At the very least, mark one column as the amount-column. It is advisable to also select a column for the description, date and the opposing account.',
+ 'job_config_roles_colum_count' => 'Column',
+ // job config for the file provider (stage: mapping):
+ 'job_config_map_title' => 'Import setup (4/4) - Connect import data to Firefly III data',
+ 'job_config_map_text' => 'In the following tables, the left value shows you information found in your uploaded file. It is your task to map this value, if possible, to a value already present in your database. Firefly will stick to this mapping. If there is no value to map to, or you do not wish to map the specific value, select nothing.',
+ 'job_config_map_nothing' => 'There is no data present in your file that you can map to existing values. Please press "Start the import" to continue.',
+ 'job_config_field_value' => 'Field value',
+ 'job_config_field_mapped' => 'Mapped to',
+ 'map_do_not_map' => '(eÅŸleÅŸtirme)',
+ 'job_config_map_submit' => 'Start the import',
+
+
+ // import status page:
+ 'import_with_key' => '\':key\' ile içe aktarın',
'status_wait_title' => 'Lütfen bekleyin...',
'status_wait_text' => 'Bu kutu bir dakika içinde kaybolacak.',
- 'status_fatal_title' => 'Önemli bir hata oluştu',
- 'status_fatal_text' => 'İçe aktarma rutininin kurtaramadığı önemli bir hata oluştu. Lütfen aşağıdaki kırmızı renkli açıklamaları okuyun.',
- 'status_fatal_more' => 'Eğer hata zaman aşımı ise, içe aktarma yarısında durdurulur. Bazı sunucu ayarlarında sadece sunucu durdurulurken içe aktarım arka planda devam eder. Bunu sağlamak için kayıt dosyalarını kontrol edin. Eğer sorun devam ederse komut satırı üzerinden içe aktarımı deneyin.',
- 'status_ready_title' => 'İçe aktarım başlamaya hazır',
- 'status_ready_text' => 'İçe aktarım başlamaya hazır. Yapmanız gereken tüm ayarlar yapıldı. Lütfen ayar dosyasını indirin. İçe aktarım planlandığı gibi gitmezse size yardım edecektir. İçe aktarımı başlatmak için takip eden komutu konsolunuza girebilir ya da web tabanlı içe aktarımı kullanabilirsiniz. Ayarlarınıza bağlı olarak göre konsol içe aktarımı size daha fazla geri bildirim verecektir.',
- 'status_ready_noconfig_text' => 'İçe aktarım başlamaya hazır. Yapmanız gereken tüm ayarlar yapıldı. İçe aktarımı başlatmak için takip eden komutu konsolunuza girebilir ya da web tabanlı içe aktarımı kullanabilirsiniz. Ayarlarınıza bağlı olarak göre konsol içe aktarımı size daha fazla geri bildirim verecektir.',
- 'status_ready_config' => 'Yapılandırmayı indir',
- 'status_ready_start' => 'İçe aktarmayı başlat',
- 'status_ready_share' => 'Lütfen ayarlarınızı indirmeyi ve onu içe aktarım ayarları merkezinde paylaşmayı düşünün. Bu diğer kullanıcılarının Firefly III\'ün dosyalarını daha kolay içe aktarmasına olanak tanır.',
- 'status_job_new' => 'Yeni iÅŸ.',
- 'status_job_configuring' => 'İçe aktarım ayarlanıyor.',
- 'status_job_configured' => 'İçe aktarım ayarlandı.',
- 'status_job_running' => 'Alma işlemi çalışıyor... Lütfen bekleyin..',
- 'status_job_error' => 'İş bir hata üretti.',
- 'status_job_finished' => 'Alma işlemi tamamlandı!',
'status_running_title' => 'İçe aktarma işlemi sürüyor',
- 'status_running_placeholder' => 'Güncelleme için lütfen bekleyin...',
- 'status_finished_title' => 'İçe aktarma rutini tamamlandı',
- 'status_finished_text' => 'İçe aktarma rutini verilerinizi içe aktardı.',
- 'status_errors_title' => 'İçe aktarım sırasında hata',
- 'status_errors_single' => 'İçe aktarım sırasında bir hata oluştu. Önemli gibi görünmüyor.',
- 'status_errors_multi' => 'İçe aktarım sırasında hatalar oluştu. Önemli gibi görünmüyorlar.',
- 'status_bread_crumb' => 'Aktarma durumu',
- 'status_sub_title' => 'Aktarma durumu',
- 'config_sub_title' => 'Hesabınızı oluşturunuz',
- 'status_finished_job' => 'The :count transactions imported can be found in tag :tag.',
- 'status_finished_no_tag' => 'Firefly III has not collected any transactions from your import file.',
- 'import_with_key' => '\':key\' ile içe aktarın',
+ 'status_job_running' => 'Please wait, running the import...',
+ 'status_job_storing' => 'Please wait, storing data...',
+ 'status_job_rules' => 'Please wait, running rules...',
+ 'status_fatal_title' => 'Fatal error',
+ 'status_fatal_text' => 'The import has suffered from an error it could not recover from. Apologies!',
+ 'status_fatal_more' => 'This (possibly very cryptic) error message is complemented by log files, which you can find on your hard drive, or in the Docker container where you run Firefly III from.',
+ 'status_finished_title' => 'Import finished',
+ 'status_finished_text' => 'The import has finished.',
+ 'finished_with_errors' => 'There were some errors during the import. Please review them carefully.',
+ 'unknown_import_result' => 'Unknown import result',
+ 'result_no_transactions' => 'No transactions have been imported. Perhaps they were all duplicates is simply no transactions where present to be imported. Perhaps the log files can tell you what happened. If you import data regularly, this is normal.',
+ 'result_one_transaction' => 'Exactly one transaction has been imported. It is stored under tag :tag where you can inspect it further.',
+ 'result_many_transactions' => 'Firefly III has imported :count transactions. They are stored under tag :tag where you can inspect them further.',
- // file, upload something
- 'file_upload_title' => 'Ayarları aktar (1/4) - Dosyalarınızı yükelyin',
- 'file_upload_text' => 'Bu yöntem dosyalarınızı bankanızdan Firefly III\'e aktarmanıza yardımcı olur. Lütfen sağ üst köşedeki yardımı kontrol edin.',
- 'file_upload_fields' => 'Alanlar',
- 'file_upload_help' => 'Dosyanızı seçin',
- 'file_upload_config_help' => 'Eğer Firefly III\'e daha önce veri aktardıysanız, ayarları sizin için önceden ayarlayacak bir ayar dosyasına sahip olabilirsiniz. Diğer kullanıcılar baı bankalar için kendi ayar dosyalarını sağlayabilirler',
- 'file_upload_type_help' => 'Yükleyeceğiniz dosya türünü seçin',
- 'file_upload_submit' => 'Dosyaları yükle',
- // file, upload types
- 'import_file_type_csv' => 'CSV (virgülle ayrılmış değerler)',
+ // general errors and warnings:
+ 'bad_job_status' => 'To access this page, your import job cannot have status ":status".',
- // file, initial config for CSV
- 'csv_initial_title' => 'Ayarları aktar (2/4) - Temel CSV aktarım ayarları',
- 'csv_initial_text' => 'Dosyanızı doğru bir şekilde içe aktarabilmek için lütfen aşağıdaki seçenekleri doğrulayın.',
- 'csv_initial_box' => 'Temel CSV aktarım ayarları',
- 'csv_initial_box_title' => 'Temel CSV aktarım ayarları seçenekleri',
- 'csv_initial_header_help' => 'CSV dosyanızın ilk satırları sütun başlıklarıysa bu kutuyu işaretleyin.',
- 'csv_initial_date_help' => 'CSV dosyanızda ki zaman biçimi. Bu sayfanın gösterdiği biçimi kontrol takip edin. Varsayılan değer şu şekilde görülen tarihleri ayrıştırır: :dateExample.',
- 'csv_initial_delimiter_help' => 'Gir dosyanızda kullanılan alan sınırlayıcıyı seçin. Emin değilseniz, virgül en güvenli seçenektir.',
- 'csv_initial_import_account_help' => 'Eğer CSV dosyanız aktif hesabınızla ilgili bilgi içermiyorsa, CSV\'de bulunan işlemlerin hangi hesaba ait olduğunu bu açılan kutudan seçiniz.',
- 'csv_initial_submit' => '3/4 adım ile devam et',
-
- // file, new options:
- 'file_apply_rules_title' => 'Kuralları uygula',
- 'file_apply_rules_description' => 'Kurallarınızı kabul ediniz. Bunun önemli ölçüde içe aktarmayı yavaşlattığını unutmayın.',
- 'file_match_bills_title' => 'Faturaları eşleştirin',
- 'file_match_bills_description' => 'Faturalarınızı yeni oluşturulan çekimlerle eşleştirin. Bunun önemli ölçüde içe aktarmayı yavaşlatacağını unutmayın.',
-
- // file, roles config
- 'csv_roles_title' => 'Ayarları aktar (3/4) - Her sütunun görevini belirleyin',
- 'csv_roles_text' => 'CSV dosyanızdaki her sütun belirli verileri içerir. Lütfen aktarıcının ne tür bir veri beklemesi gerektiğini belirtin. Verileri "planla" seçeneği sütunda bulunan her girdinin veri tabanınınızdaki bir değer ile bağlantılanması anlamına gelir. Genellikle planlanan sütun karşı hesabın IBAN numarasının olduğu sütundur. Bu veri tabanınızda bulunan IBAN\'larla kolayca eşleştirilebilir.',
- 'csv_roles_table' => 'Tablo',
- 'csv_roles_column_name' => 'Sütun adı',
- 'csv_roles_column_example' => 'Sütun örneği verileri',
- 'csv_roles_column_role' => 'Sütun veri ortalaması',
- 'csv_roles_do_map_value' => 'Değerlerin haritası',
- 'csv_roles_column' => 'Sütun',
- 'csv_roles_no_example_data' => 'Örnek veri yok',
- 'csv_roles_submit' => '4/4 adım ile devam et',
-
- // not csv, but normal warning
- 'roles_warning' => 'At the very least, mark one column as the amount-column. It is advisable to also select a column for the description, date and the opposing account.',
- 'foreign_amount_warning' => 'If you mark a column as containing an amount in a foreign currency, you must also set the column that contains which currency it is.',
-
- // file, map data
- 'file_map_title' => 'Ayarları aktar (4/4) - İçe aktarım verilerini Firefly III verilerine bağlayın',
- 'file_map_text' => 'Takip eden tabloda, sol değer yüklediğiniz dosyada bulunan bilgileri gösterir. Bu değeri eşlemek sizin göreviniz, eğer mümkünse veritabanınızda bulunan bir değerle. Firefly bu eşlemeye bağlı kalacak. Eğer eşleştirilecek değer yoksa ya da belirli bir değer ile eşleştirmek istemiyorsanız hiçbir şey seçmeyin.',
- 'file_map_field_value' => 'Alan deÄŸeri',
- 'file_map_field_mapped_to' => 'EÅŸleÅŸti',
- 'map_do_not_map' => '(eÅŸleÅŸtirme)',
- 'file_map_submit' => 'İçe aktarmaya başla',
- 'file_nothing_to_map' => 'There is no data present in your file that you can map to existing values. Please press "Start the import" to continue.',
-
- // map things.
+ // column roles for CSV import:
'column__ignore' => '(bu sütünu yok say)',
'column_account-iban' => 'Öğe hesabı (IBAN)',
'column_account-id' => 'Asset account ID (matching FF3)',
@@ -158,48 +261,4 @@ return [
'column_note' => 'Not(lar)',
'column_internal-reference' => 'Internal reference',
- // prerequisites
- 'prerequisites' => 'Prerequisites',
-
- // bunq
- 'bunq_prerequisites_title' => 'Bunq\'dan içeri aktarım için şartlar',
- 'bunq_prerequisites_text' => 'In order to import from bunq, you need to obtain an API key. You can do this through the app. Please note that the import function for bunq is in BETA. It has only been tested against the sandbox API.',
- 'bunq_prerequisites_text_ip' => 'Bunq requires your externally facing IP address. Firefly III has tried to fill this in using the ipify service. Make sure this IP address is correct, or the import will fail.',
- 'bunq_do_import' => 'Yes, import from this account',
- 'bunq_accounts_title' => 'Bunq accounts',
- 'bunq_accounts_text' => 'These are the accounts associated with your bunq account. Please select the accounts from which you want to import, and in which account the transactions must be imported.',
-
- // Spectre
- 'spectre_title' => 'Spectre kullanarak içe aktar',
- 'spectre_prerequisites_title' => 'Spectre kullanarak içe aktarma için ön koşullar',
- 'spectre_prerequisites_text' => 'In order to import data using the Spectre API (v4), you must provide Firefly III with two secret values. They can be found on the secrets page.',
- 'spectre_enter_pub_key' => 'The import will only work when you enter this public key on your secrets page.',
- 'spectre_accounts_title' => 'Select accounts to import from',
- 'spectre_accounts_text' => 'Each account on the left below has been found by Spectre and can be imported into Firefly III. Please select the asset account that should hold any given transactions. If you do not wish to import from any particular account, remove the check from the checkbox.',
- 'spectre_do_import' => 'Yes, import from this account',
- 'spectre_no_supported_accounts' => 'You cannot import from this account due to a currency mismatch.',
-
- // keys from "extra" array:
- 'spectre_extra_key_iban' => 'IBAN',
- 'spectre_extra_key_swift' => 'SWIFT',
- 'spectre_extra_key_status' => 'Status',
- 'spectre_extra_key_card_type' => 'Card type',
- 'spectre_extra_key_account_name' => 'Account name',
- 'spectre_extra_key_client_name' => 'Client name',
- 'spectre_extra_key_account_number' => 'Account number',
- 'spectre_extra_key_blocked_amount' => 'Blocked amount',
- 'spectre_extra_key_available_amount' => 'Available amount',
- 'spectre_extra_key_credit_limit' => 'Credit limit',
- 'spectre_extra_key_interest_rate' => 'Interest rate',
- 'spectre_extra_key_expiry_date' => 'Expiry date',
- 'spectre_extra_key_open_date' => 'Open date',
- 'spectre_extra_key_current_time' => 'Current time',
- 'spectre_extra_key_current_date' => 'Current date',
- 'spectre_extra_key_cards' => 'Cards',
- 'spectre_extra_key_units' => 'Units',
- 'spectre_extra_key_unit_price' => 'Unit price',
- 'spectre_extra_key_transactions_count' => 'Transaction count',
-
- // various other strings:
- 'imported_from_account' => 'Imported from ":account"',
];
diff --git a/resources/lang/tr_TR/intro.php b/resources/lang/tr_TR/intro.php
index ed21bd0c27..6e4291b465 100644
--- a/resources/lang/tr_TR/intro.php
+++ b/resources/lang/tr_TR/intro.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
// index
'index_intro' => 'Firefly III indeks sayfasına hoşgeldiniz. Firefly III\'nin nasıl çalıştığını öğrenmek için lütfen bu tanıtımı izleyin.',
diff --git a/resources/lang/tr_TR/list.php b/resources/lang/tr_TR/list.php
index 016da06ac2..4b2516e5f6 100644
--- a/resources/lang/tr_TR/list.php
+++ b/resources/lang/tr_TR/list.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
'buttons' => 'TuÅŸlar',
'icon' => 'Simge',
@@ -111,10 +112,15 @@ return [
'sepa-cc' => 'SEPA Clearing Code',
'sepa-ep' => 'SEPA External Purpose',
'sepa-ci' => 'SEPA Creditor Identifier',
+ 'external_id' => 'External ID',
'account_at_bunq' => 'Account with bunq',
'file_name' => 'File name',
'file_size' => 'File size',
'file_type' => 'File type',
'attached_to' => 'Attached to',
'file_exists' => 'File exists',
+ 'spectre_bank' => 'Bank',
+ 'spectre_last_use' => 'Last login',
+ 'spectre_status' => 'Status',
+ 'bunq_payment_id' => 'bunq payment ID',
];
diff --git a/resources/lang/tr_TR/pagination.php b/resources/lang/tr_TR/pagination.php
index 4b82910d66..5022bed68c 100644
--- a/resources/lang/tr_TR/pagination.php
+++ b/resources/lang/tr_TR/pagination.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
'previous' => '« Önceki',
'next' => 'Sonraki »',
diff --git a/resources/lang/tr_TR/passwords.php b/resources/lang/tr_TR/passwords.php
index a013bf7294..3a312f2358 100644
--- a/resources/lang/tr_TR/passwords.php
+++ b/resources/lang/tr_TR/passwords.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
'password' => 'Şifreniz en az altı karakter olmalıdır ve onayla eşleşmelidir.',
'user' => 'Bu e-posta adresine sahip bir kullanıcı bulunamadı.',
diff --git a/resources/lang/tr_TR/validation.php b/resources/lang/tr_TR/validation.php
index 00adb5581e..7a4374c4d5 100644
--- a/resources/lang/tr_TR/validation.php
+++ b/resources/lang/tr_TR/validation.php
@@ -1,9 +1,8 @@
.
*/
+declare(strict_types=1);
+
return [
'iban' => 'Bu IBAN geçerli değilrdir.',
'source_equals_destination' => 'The source account equals the destination account',
@@ -109,7 +110,8 @@ return [
'in_array' => ':attribute alanı :other içinde olamaz.',
'present' => ':attribute alanı mevcut olmalıdır.',
'amount_zero' => 'Toplam tutar sıfır olamaz',
- 'secure_password' => 'Güvenli bir şifre değildir. Lütfen tekrar deneyin. Daha fazla bilgi için https://goo.gl/NCh2tN adresini ziyaret edin',
+ 'unique_piggy_bank_for_user' => 'The name of the piggy bank must be unique.',
+ 'secure_password' => 'This is not a secure password. Please try again. For more information, visit http://bit.ly/FF3-password-security',
'attributes' => [
'email' => 'email address',
'description' => 'description',
diff --git a/resources/views/bills/create.twig b/resources/views/bills/create.twig
index a2663bff18..9bfde12466 100644
--- a/resources/views/bills/create.twig
+++ b/resources/views/bills/create.twig
@@ -17,7 +17,7 @@
+ Somebody (hopefully you) just created a new Firefly III API Access Token for your user account. +
+ ++ With this token, they can access all of your financial records through the Firefly III API. +
+ ++ If this wasn't you, please revoke this token as soon as possible at {{ route('profile.index') }}. +
+{% include 'emails.footer-html' %} diff --git a/resources/views/emails/access-token-created-text.twig b/resources/views/emails/access-token-created-text.twig new file mode 100644 index 0000000000..5ea41eb0fe --- /dev/null +++ b/resources/views/emails/access-token-created-text.twig @@ -0,0 +1,7 @@ +{% include 'emails.header-text' %} +Somebody (hopefully you) just created a new Firefly III API Access Token for your user account. + +With this token, they can access all of your financial records through the Firefly III API. + +If this wasn't you, please revoke this token as soon as possible at {{ route('profile.index') }}. +{% include 'emails.footer-text' %} diff --git a/resources/views/emails/error-html.twig b/resources/views/emails/error-html.twig index f3126c63e5..0e0f2004f0 100644 --- a/resources/views/emails/error-html.twig +++ b/resources/views/emails/error-html.twig @@ -24,7 +24,9 @@
- The IP address related to this error is: {{ ip }}
+ The IP address related to this error is: {{ ip }}
+ URL is: {{ url }}
+ User agent: {{ userAgent }}
diff --git a/resources/views/emails/error-text.twig b/resources/views/emails/error-text.twig index 56d4ea7a39..6cc100d81a 100644 --- a/resources/views/emails/error-text.twig +++ b/resources/views/emails/error-text.twig @@ -14,6 +14,8 @@ This error occured in file "{{ file }}" on line {{ line }} with code {{ code }}. {% endif %} The IP address related to this error is: {{ ip }} +URL is: {{ url }} +User agent: {{ userAgent }} The full stacktrace is below. If you think this is a bug in Firefly III, you can forward this message to thegrumpydictator@gmail.com. This can help fix diff --git a/resources/views/emails/oauth-client-created-html.twig b/resources/views/emails/oauth-client-created-html.twig new file mode 100644 index 0000000000..f49cd54b34 --- /dev/null +++ b/resources/views/emails/oauth-client-created-html.twig @@ -0,0 +1,14 @@ +{% include 'emails.header-html' %} +
+ Somebody (hopefully you) just created a new Firefly III API OAuth Client for your user account. It's labeled "{{ client.name }}" + and has callback URL {{ client.redirect }}. +
+ ++ With this client, they can access all of your financial records through the Firefly III API. +
+ ++ If this wasn't you, please revoke this client as soon as possible at {{ route('profile.index') }}. +
+{% include 'emails.footer-html' %} diff --git a/resources/views/emails/oauth-client-created-text.twig b/resources/views/emails/oauth-client-created-text.twig new file mode 100644 index 0000000000..d74222d0f4 --- /dev/null +++ b/resources/views/emails/oauth-client-created-text.twig @@ -0,0 +1,9 @@ +{% include 'emails.header-text' %} +Somebody (hopefully you) just created a new Firefly III API OAuth Client for your user account. It's labeled "{{ client.name }}" and has callback URL: + +{{ client.redirect }} + +With this client, they can access all of your financial records through the Firefly III API. + +If this wasn't you, please revoke this client as soon as possible at {{ route('profile.index') }}. +{% include 'emails.footer-text' %} diff --git a/resources/views/export/index.twig b/resources/views/export/index.twig index a772feb710..57851bf641 100644 --- a/resources/views/export/index.twig +++ b/resources/views/export/index.twig @@ -74,7 +74,7 @@ {# ACCOUNTS #} - {{ ExpandedForm.multiCheckbox('accounts',accountList, checked, {' class': 'account-checkbox'}) }} + {{ ExpandedForm.assetAccountCheckList('accounts', {' class': 'account-checkbox','select_all': true}) }} {{ ExpandedForm.checkbox('include_attachments','1', true) }} diff --git a/resources/views/form/assetAccountCheckList.twig b/resources/views/form/assetAccountCheckList.twig new file mode 100644 index 0000000000..129dc11356 --- /dev/null +++ b/resources/views/form/assetAccountCheckList.twig @@ -0,0 +1,24 @@ +