This code fixes #349

This commit is contained in:
James Cole 2016-10-20 19:10:43 +02:00
parent b9308cd74a
commit d92768ecbf
9 changed files with 248 additions and 48 deletions

View File

@ -0,0 +1,153 @@
<?php
/**
* CreateImport.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International License.
*
* See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Console\Commands;
use Artisan;
use FireflyIII\Models\ImportJob;
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
use FireflyIII\Repositories\User\UserRepositoryInterface;
use Illuminate\Console\Command;
use Log;
/**
* Class CreateImport
*
* @package FireflyIII\Console\Commands
*/
class CreateImport extends Command
{
/**
* The console command description.
*
* @var string
*/
protected $description = 'Use this command to create a new import. Your user ID can be found on the /profile page.';
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'firefly:create-import {file} {configuration} {--user=1} {--type=csv} {--start}';
/**
* Create a new command instance.
*
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
// find the file
/** @var UserRepositoryInterface $userRepository */
$userRepository = app(UserRepositoryInterface::class);
$file = $this->argument('file');
$configuration = $this->argument('configuration');
$user = $userRepository->find(intval($this->option('user')));
$cwd = getcwd();
$type = strtolower($this->option('type'));
if (!$this->validArguments()) {
return;
}
// try to parse configuration data:
$configurationData = json_decode(file_get_contents($configuration));
if (is_null($configurationData)) {
$this->error(sprintf('Firefly III cannot read the contents of configuration file "%s" (working directory: "%s").', $configuration, $cwd));
return;
}
$this->info(sprintf('Going to create a job to import file: %s', $file));
$this->info(sprintf('Using configuration file: %s', $configuration));
$this->info(sprintf('Import into user: #%d (%s)', $user->id, $user->email));
$this->info(sprintf('Type of import: %s', $type));
/** @var ImportJobRepositoryInterface $jobRepository */
$jobRepository = app(ImportJobRepositoryInterface::class, [$user]);
$job = $jobRepository->create($type);
$this->line(sprintf('Created job "%s"...', $job->key));
// put the file in the proper place:
Artisan::call('firefly:encrypt', ['file' => $file, 'key' => $job->key]);
$this->line('Stored import data...');
// store the configuration in the job:
$job->configuration = $configurationData;
$job->status = 'settings_complete';
$job->save();
$this->line('Stored configuration...');
// if user wants to run it, do!
if ($this->option('start') === true) {
$this->line('The import will start in a moment. This process is not visible...');
Log::debug('Go for import!');
Artisan::call('firefly:start-import', ['key' => $job->key]);
$this->line('Done!');
}
return;
}
/**
* @return bool
*/
private function validArguments(): bool
{
// find the file
/** @var UserRepositoryInterface $userRepository */
$userRepository = app(UserRepositoryInterface::class);
$file = $this->argument('file');
$configuration = $this->argument('configuration');
$user = $userRepository->find(intval($this->option('user')));
$cwd = getcwd();
$validTypes = array_keys(config('firefly.import_formats'));
$type = strtolower($this->option('type'));
if (is_null($user->id)) {
$this->error(sprintf('There is no user with ID %d.', $this->option('user')));
return false;
}
if (!in_array($type, $validTypes)) {
$this->error(sprintf('Cannot import file of type "%s"', $type));
return false;
}
if (!file_exists($file)) {
$this->error(sprintf('Firefly III cannot find file "%s" (working directory: "%s").', $file, $cwd));
return false;
}
if (!file_exists($configuration)) {
$this->error(sprintf('Firefly III cannot find configuration file "%s" (working directory: "%s").', $configuration, $cwd));
return false;
}
return true;
}
}

View File

@ -32,14 +32,14 @@ class Import extends Command
*
* @var string
*/
protected $description = 'Import stuff into Firefly III.';
protected $description = 'This will start a new import.';
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'firefly:import {key}';
protected $signature = 'firefly:start-import {key}';
/**
* Create a new command instance.
@ -57,9 +57,11 @@ class Import extends Command
*/
public function handle()
{
Log::debug('Start start-import command');
$jobKey = $this->argument('key');
$job = ImportJob::whereKey($jobKey)->first();
if (!$this->isValid($job)) {
Log::error('Job is not valid for some reason. Exit.');
return;
}

View File

@ -13,6 +13,7 @@ declare(strict_types = 1);
namespace FireflyIII\Console;
use FireflyIII\Console\Commands\CreateImport;
use FireflyIII\Console\Commands\EncryptFile;
use FireflyIII\Console\Commands\Import;
use FireflyIII\Console\Commands\ScanAttachments;
@ -58,6 +59,7 @@ class Kernel extends ConsoleKernel
UpgradeFireflyInstructions::class,
VerifyDatabase::class,
Import::class,
CreateImport::class,
EncryptFile::class,
ScanAttachments::class,
UpgradeDatabase::class,

View File

@ -35,6 +35,9 @@ class ProfileController extends Controller
public function __construct()
{
parent::__construct();
View::share('title', trans('firefly.profile'));
View::share('mainTitleIcon', 'fa-user');
}
/**
@ -63,7 +66,10 @@ class ProfileController extends Controller
*/
public function index()
{
return view('profile.index')->with('title', trans('firefly.profile'))->with('subTitle', auth()->user()->email)->with('mainTitleIcon', 'fa-user');
$subTitle = auth()->user()->email;
$userId = auth()->user()->id;
return view('profile.index', compact('subTitle', 'userId'));
}
/**

View File

@ -13,6 +13,7 @@ declare(strict_types = 1);
namespace FireflyIII\Import\Converter;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Account;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use Log;
@ -69,11 +70,20 @@ class OpposingAccountIban extends BasicConverter implements ConverterInterface
return $account;
}
$account = $repository->store(
['name' => $value, 'iban' => $value, 'user' => $this->user->id, 'accountType' => 'import', 'virtualBalance' => 0, 'active' => true,
'openingBalance' => 0]
);
$this->setCertainty(100);
// the IBAN given may not be a valid IBAN. If not, we cannot store by
// iban and we have no opposing account. There should be some kind of fall back
// routine.
try {
$account = $repository->store(
['name' => $value, 'iban' => $value, 'user' => $this->user->id, 'accountType' => 'import', 'virtualBalance' => 0, 'active' => true,
'openingBalance' => 0]
);
$this->setCertainty(100);
} catch (FireflyException $e) {
Log::error($e);
$account = new Account;
}
return $account;
}

View File

@ -59,6 +59,21 @@ class UserRepository implements UserRepositoryInterface
return $this->all()->count();
}
/**
* @param int $userId
*
* @return User
*/
public function find(int $userId): User
{
$user = User::find($userId);
if (!is_null($user)) {
return $user;
}
return new User;
}
/**
* Return basic user information.
*

View File

@ -31,6 +31,13 @@ interface UserRepositoryInterface
*/
public function all(): Collection;
/**
* @param int $userId
*
* @return User
*/
public function find(int $userId): User;
/**
* Return basic user information.
*

View File

@ -69,6 +69,7 @@ return [
'no_budget_pointer' => 'You seem to have no budgets yet. You should create some on the <a href="/budgets">budgets</a>-page. Budgets can help you keep track of expenses.',
'source_accounts' => 'Source account(s)',
'destination_accounts' => 'Destination account(s)',
'user_id_is' => 'Your user id is <strong>:user</strong>',
// repeat frequencies:
'repeat_freq_monthly' => 'monthly',
@ -669,48 +670,49 @@ return [
'add_money_to_piggy_title' => 'Add money to piggy bank ":name"',
'remove_money_from_piggy_title' => 'Remove money from piggy bank ":name"',
'add' => 'Add',
'remove' => 'Remove',
'max_amount_add' => 'The maximum amount you can add is',
'max_amount_remove' => 'The maximum amount you can remove is',
'update_piggy_button' => 'Update piggy bank',
'update_piggy_title' => 'Update piggy bank ":name"',
'updated_piggy_bank' => 'Updated piggy bank ":name"',
'details' => 'Details',
'events' => 'Events',
'target_amount' => 'Target amount',
'start_date' => 'Start date',
'target_date' => 'Target date',
'no_target_date' => 'No target date',
'todo' => 'to do',
'table' => 'Table',
'piggy_bank_not_exists' => 'Piggy bank no longer exists.',
'add_any_amount_to_piggy' => 'Add money to this piggy bank to reach your target of :amount.',
'add_set_amount_to_piggy' => 'Add :amount to fill this piggy bank on :date',
'delete_piggy_bank' => 'Delete piggy bank ":name"',
'cannot_add_amount_piggy' => 'Could not add :amount to ":name".',
'deleted_piggy_bank' => 'Deleted piggy bank ":name"',
'added_amount_to_piggy' => 'Added :amount to ":name"',
'removed_amount_from_piggy' => 'Removed :amount from ":name"',
'cannot_remove_amount_piggy' => 'Could not remove :amount from ":name".',
'remove' => 'Remove',
'max_amount_add' => 'The maximum amount you can add is',
'max_amount_remove' => 'The maximum amount you can remove is',
'update_piggy_button' => 'Update piggy bank',
'update_piggy_title' => 'Update piggy bank ":name"',
'updated_piggy_bank' => 'Updated piggy bank ":name"',
'details' => 'Details',
'events' => 'Events',
'target_amount' => 'Target amount',
'start_date' => 'Start date',
'target_date' => 'Target date',
'no_target_date' => 'No target date',
'todo' => 'to do',
'table' => 'Table',
'piggy_bank_not_exists' => 'Piggy bank no longer exists.',
'add_any_amount_to_piggy' => 'Add money to this piggy bank to reach your target of :amount.',
'add_set_amount_to_piggy' => 'Add :amount to fill this piggy bank on :date',
'delete_piggy_bank' => 'Delete piggy bank ":name"',
'cannot_add_amount_piggy' => 'Could not add :amount to ":name".',
'deleted_piggy_bank' => 'Deleted piggy bank ":name"',
'added_amount_to_piggy' => 'Added :amount to ":name"',
'removed_amount_from_piggy' => 'Removed :amount from ":name"',
'cannot_remove_amount_piggy' => 'Could not remove :amount from ":name".',
// tags
'regular_tag' => 'Just a regular tag.',
'balancing_act' => 'The tag takes at most two transactions; an expense and a transfer. They\'ll balance each other out.',
'advance_payment' => 'The tag accepts one expense and any number of deposits aimed to repay the original expense.',
'delete_tag' => 'Delete tag ":tag"',
'deleted_tag' => 'Deleted tag ":tag"',
'new_tag' => 'Make new tag',
'edit_tag' => 'Edit tag ":tag"',
'updated_tag' => 'Updated tag ":tag"',
'created_tag' => 'Tag ":tag" has been created!',
'no_year' => 'No year set',
'no_month' => 'No month set',
'tag_title_nothing' => 'Default tags',
'tag_title_balancingAct' => 'Balancing act tags',
'tag_title_advancePayment' => 'Advance payment tags',
'tags_introduction' => 'Usually tags are singular words, designed to quickly band items together using things like <span class="label label-info">expensive</span>, <span class="label label-info">bill</span> or <span class="label label-info">for-party</span>. In Firefly III, tags can have more properties such as a date, description and location. This allows you to join transactions together in a more meaningful way. For example, you could make a tag called <span class="label label-success"> Christmas dinner with friends</span> and add information about the restaurant. Such tags are "singular", you would only use them for a single occasion, perhaps with multiple transactions.',
'tags_group' => 'Tags group transactions together, which makes it possible to store reimbursements (in case you front money for others) and other "balancing acts" where expenses are summed up (the payments on your new TV) or where expenses and deposits are cancelling each other out (buying something with saved money). It\'s all up to you. Using tags the old-fashioned way is of course always possible.',
'tags_start' => 'Create a tag to get started or enter tags when creating new transactions.',
'regular_tag' => 'Just a regular tag.',
'balancing_act' => 'The tag takes at most two transactions; an expense and a transfer. They\'ll balance each other out.',
'advance_payment' => 'The tag accepts one expense and any number of deposits aimed to repay the original expense.',
'delete_tag' => 'Delete tag ":tag"',
'deleted_tag' => 'Deleted tag ":tag"',
'new_tag' => 'Make new tag',
'edit_tag' => 'Edit tag ":tag"',
'updated_tag' => 'Updated tag ":tag"',
'created_tag' => 'Tag ":tag" has been created!',
'no_year' => 'No year set',
'no_month' => 'No month set',
'tag_title_nothing' => 'Default tags',
'tag_title_balancingAct' => 'Balancing act tags',
'tag_title_advancePayment' => 'Advance payment tags',
'tags_introduction' => 'Usually tags are singular words, designed to quickly band items together using things like <span class="label label-info">expensive</span>, <span class="label label-info">bill</span> or <span class="label label-info">for-party</span>. In Firefly III, tags can have more properties such as a date, description and location. This allows you to join transactions together in a more meaningful way. For example, you could make a tag called <span class="label label-success"> Christmas dinner with friends</span> and add information about the restaurant. Such tags are "singular", you would only use them for a single occasion, perhaps with multiple transactions.',
'tags_group' => 'Tags group transactions together, which makes it possible to store reimbursements (in case you front money for others) and other "balancing acts" where expenses are summed up (the payments on your new TV) or where expenses and deposits are cancelling each other out (buying something with saved money). It\'s all up to you. Using tags the old-fashioned way is of course always possible.',
'tags_start' => 'Create a tag to get started or enter tags when creating new transactions.',
'transaction_journal_information' => 'Transaction information',
'transaction_journal_meta' => 'Meta information',

View File

@ -12,6 +12,9 @@
<h3 class="box-title">Options</h3>
</div>
<div class="box-body">
<p>
{{ trans('firefly.user_id_is',{user: userId})|raw }}
</p>
<ul>
<li><a href="{{ route('profile.change-password') }}">{{ 'change_your_password'|_ }}</a></li>
<li><a class="text-danger" href="{{ route('profile.delete-account') }}">{{ 'delete_account'|_ }}</a></li>